channels/gfx: add surface table helper, surface creation/deletion
This commit is contained in:
parent
2a82684521
commit
fbea223ecf
@ -854,11 +854,41 @@ static int rdpgfx_plugin_terminated(IWTSPlugin* pPlugin)
|
||||
|
||||
zgfx_context_free(gfx->zgfx);
|
||||
|
||||
HashTable_Free(gfx->SurfaceTable);
|
||||
|
||||
free(gfx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rdpgfx_set_surface_data(RdpgfxClientContext* context, UINT16 surfaceId, void* pData)
|
||||
{
|
||||
ULONG_PTR key;
|
||||
RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) context->handle;
|
||||
|
||||
key = ((ULONG_PTR) surfaceId) + 1;
|
||||
|
||||
if (pData)
|
||||
HashTable_Add(gfx->SurfaceTable, (void*) key, pData);
|
||||
else
|
||||
HashTable_Remove(gfx->SurfaceTable, (void*) key);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void* rdpgfx_get_surface_data(RdpgfxClientContext* context, UINT16 surfaceId)
|
||||
{
|
||||
ULONG_PTR key;
|
||||
void* pData = NULL;
|
||||
RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) context->handle;
|
||||
|
||||
key = ((ULONG_PTR) surfaceId) + 1;
|
||||
|
||||
pData = HashTable_GetItemValue(gfx->SurfaceTable, (void*) key);
|
||||
|
||||
return pData;
|
||||
}
|
||||
|
||||
#ifdef STATIC_CHANNELS
|
||||
#define DVCPluginEntry rdpgfx_DVCPluginEntry
|
||||
#endif
|
||||
@ -885,6 +915,11 @@ int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
|
||||
gfx->iface.Disconnected = NULL;
|
||||
gfx->iface.Terminated = rdpgfx_plugin_terminated;
|
||||
|
||||
gfx->SurfaceTable = HashTable_New(TRUE);
|
||||
|
||||
if (!gfx->SurfaceTable)
|
||||
return -1;
|
||||
|
||||
context = (RdpgfxClientContext*) calloc(1, sizeof(RdpgfxClientContext));
|
||||
|
||||
if (!context)
|
||||
@ -892,6 +927,9 @@ int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
|
||||
|
||||
context->handle = (void*) gfx;
|
||||
|
||||
context->SetSurfaceData = rdpgfx_set_surface_data;
|
||||
context->GetSurfaceData = rdpgfx_get_surface_data;
|
||||
|
||||
gfx->iface.pInterface = (void*) context;
|
||||
|
||||
gfx->zgfx = zgfx_context_new(FALSE);
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <freerdp/addin.h>
|
||||
|
||||
#include <winpr/wlog.h>
|
||||
#include <winpr/collections.h>
|
||||
|
||||
#include <freerdp/client/rdpgfx.h>
|
||||
|
||||
@ -66,6 +67,8 @@ struct _RDPGFX_PLUGIN
|
||||
ZGFX_CONTEXT* zgfx;
|
||||
UINT32 UnacknowledgedFrames;
|
||||
UINT32 TotalDecodedFrames;
|
||||
|
||||
wHashTable* SurfaceTable;
|
||||
};
|
||||
typedef struct _RDPGFX_PLUGIN RDPGFX_PLUGIN;
|
||||
|
||||
|
@ -306,16 +306,52 @@ int xf_DeleteEncodingContext(RdpgfxClientContext* context, RDPGFX_DELETE_ENCODIN
|
||||
|
||||
int xf_CreateSurface(RdpgfxClientContext* context, RDPGFX_CREATE_SURFACE_PDU* createSurface)
|
||||
{
|
||||
xfGfxSurface* surface;
|
||||
xfContext* xfc = (xfContext*) context->custom;
|
||||
|
||||
printf("xf_CreateSurface: surfaceId: %d width: %d height: %d format: 0x%02X\n",
|
||||
createSurface->surfaceId, createSurface->width, createSurface->height, createSurface->pixelFormat);
|
||||
|
||||
surface = (xfGfxSurface*) calloc(1, sizeof(xfGfxSurface));
|
||||
|
||||
if (!surface)
|
||||
return -1;
|
||||
|
||||
surface->surfaceId = createSurface->surfaceId;
|
||||
surface->width = (UINT32) createSurface->width;
|
||||
surface->height = (UINT32) createSurface->height;
|
||||
surface->alpha = (createSurface->pixelFormat == PIXEL_FORMAT_ARGB_8888) ? TRUE : FALSE;
|
||||
|
||||
surface->data = (BYTE*) calloc(1, surface->width * surface->height * 4);
|
||||
|
||||
if (!surface->data)
|
||||
return -1;
|
||||
|
||||
surface->image = XCreateImage(xfc->display, xfc->visual, 24, ZPixmap, 0,
|
||||
(char*) surface->data, surface->width, surface->height, 32, 0);
|
||||
|
||||
context->SetSurfaceData(context, surface->surfaceId, (void*) surface);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int xf_DeleteSurface(RdpgfxClientContext* context, RDPGFX_DELETE_SURFACE_PDU* deleteSurface)
|
||||
{
|
||||
xfGfxSurface* surface = NULL;
|
||||
|
||||
surface = (xfGfxSurface*) context->GetSurfaceData(context, deleteSurface->surfaceId);
|
||||
|
||||
printf("xf_DeleteSurface: surfaceId: %d\n", deleteSurface->surfaceId);
|
||||
|
||||
if (surface)
|
||||
{
|
||||
XFree(surface->image);
|
||||
free(surface->data);
|
||||
free(surface);
|
||||
}
|
||||
|
||||
context->SetSurfaceData(context, deleteSurface->surfaceId, NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,17 @@
|
||||
#include "xf_client.h"
|
||||
#include "xfreerdp.h"
|
||||
|
||||
struct xf_gfx_surface
|
||||
{
|
||||
UINT16 surfaceId;
|
||||
UINT32 width;
|
||||
UINT32 height;
|
||||
BOOL alpha;
|
||||
BYTE* data;
|
||||
XImage* image;
|
||||
};
|
||||
typedef struct xf_gfx_surface xfGfxSurface;
|
||||
|
||||
void xf_register_graphics_pipeline(xfContext* xfc, RdpgfxClientContext* gfx);
|
||||
|
||||
#endif /* __XF_GRAPHICS_PIPELINE_H */
|
||||
|
@ -45,6 +45,9 @@ typedef int (*pcRdpgfxEvictCacheEntry)(RdpgfxClientContext* context, RDPGFX_EVIC
|
||||
typedef int (*pcRdpgfxMapSurfaceToOutput)(RdpgfxClientContext* context, RDPGFX_MAP_SURFACE_TO_OUTPUT_PDU* surfaceToOutput);
|
||||
typedef int (*pcRdpgfxMapSurfaceToWindow)(RdpgfxClientContext* context, RDPGFX_MAP_SURFACE_TO_WINDOW_PDU* surfaceToWindow);
|
||||
|
||||
typedef int (*pcRdpgfxSetSurfaceData)(RdpgfxClientContext* context, UINT16 surfaceId, void* pData);
|
||||
typedef void* (*pcRdpgfxGetSurfaceData)(RdpgfxClientContext* context, UINT16 surfaceId);
|
||||
|
||||
struct _rdpgfx_client_context
|
||||
{
|
||||
void* handle;
|
||||
@ -66,6 +69,9 @@ struct _rdpgfx_client_context
|
||||
pcRdpgfxEvictCacheEntry EvictCacheEntry;
|
||||
pcRdpgfxMapSurfaceToOutput MapSurfaceToOutput;
|
||||
pcRdpgfxMapSurfaceToWindow MapSurfaceToWindow;
|
||||
|
||||
pcRdpgfxSetSurfaceData SetSurfaceData;
|
||||
pcRdpgfxGetSurfaceData GetSurfaceData;
|
||||
};
|
||||
|
||||
#endif /* FREERDP_CHANNEL_CLIENT_RDPGFX_H */
|
||||
|
Loading…
Reference in New Issue
Block a user