summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrederic Plourde <frederic.plourde@collabora.com>2012-09-12 10:48:32 -0400
committerDaniel Stone <daniel@fooishbar.org>2012-09-25 17:16:38 +1000
commite3903a9383351b061b1a99dfc653ca50de764ec4 (patch)
tree58fdb1273cf9999822fe5dc1334d9a43f7abe52b
parent11afebc92ce1a7462ff2886286504425b1c8f0ba (diff)
Add glXCreateNewContext support in Xephyr #54798
Similar to how we intercept and pass through CreateContext, also pass through newer CreateNewContext requests. Fixes Clutter → Xephyr → VirtualBox. Signed-off-by: Frederic Plourde <frederic.plourde@collabora.com> Reviewed-by: Daniel Stone <daniel@fooishbar.org>
-rw-r--r--hw/kdrive/ephyr/ephyrglxext.c63
-rw-r--r--hw/kdrive/ephyr/ephyrhostglx.c54
-rw-r--r--hw/kdrive/ephyr/ephyrhostglx.h7
3 files changed, 107 insertions, 17 deletions
diff --git a/hw/kdrive/ephyr/ephyrglxext.c b/hw/kdrive/ephyr/ephyrglxext.c
index 892d99f30..22d510891 100644
--- a/hw/kdrive/ephyr/ephyrglxext.c
+++ b/hw/kdrive/ephyr/ephyrglxext.c
@@ -61,6 +61,8 @@ int ephyrGLXGetFBConfigsSGIX(__GLXclientState * a_cl, GLbyte * a_pc);
int ephyrGLXGetFBConfigsSGIXSwap(__GLXclientState * a_cl, GLbyte * a_pc);
int ephyrGLXCreateContext(__GLXclientState * a_cl, GLbyte * a_pc);
int ephyrGLXCreateContextSwap(__GLXclientState * a_cl, GLbyte * a_pc);
+int ephyrGLXCreateNewContext(__GLXclientState * a_cl, GLbyte * a_pc);
+int ephyrGLXCreateNewContextSwap(__GLXclientState * a_cl, GLbyte * a_pc);
int ephyrGLXDestroyContext(__GLXclientState * a_cl, GLbyte * a_pc);
int ephyrGLXDestroyContextSwap(__GLXclientState * a_cl, GLbyte * a_pc);
int ephyrGLXMakeCurrent(__GLXclientState * a_cl, GLbyte * a_pc);
@@ -112,6 +114,9 @@ ephyrHijackGLXExtension(void)
dispatch_functions[X_GLXCreateContext][0] = ephyrGLXCreateContext;
dispatch_functions[X_GLXCreateContext][1] = ephyrGLXCreateContextSwap;
+ dispatch_functions[X_GLXCreateNewContext][0] = ephyrGLXCreateNewContext;
+ dispatch_functions[X_GLXCreateNewContext][1] = ephyrGLXCreateNewContextSwap;
+
dispatch_functions[X_GLXDestroyContext][0] = ephyrGLXDestroyContext;
dispatch_functions[X_GLXDestroyContext][1] = ephyrGLXDestroyContextSwap;
@@ -459,7 +464,8 @@ ephyrGLXCreateContextReal(xGLXCreateContextReq * a_req, Bool a_do_swap)
if (!ephyrHostGLXCreateContext(a_req->screen,
host_w_attrs.visualid,
a_req->context,
- a_req->shareList, a_req->isDirect)) {
+ a_req->shareList, 0,
+ a_req->isDirect, X_GLXCreateContext)) {
EPHYR_LOG_ERROR("ephyrHostGLXCreateContext() failed\n");
goto out;
}
@@ -469,6 +475,45 @@ ephyrGLXCreateContextReal(xGLXCreateContextReq * a_req, Bool a_do_swap)
return res;
}
+static int
+ephyrGLXCreateNewContextReal(xGLXCreateNewContextReq * a_req, Bool a_do_swap)
+{
+ int res = BadImplementation;
+
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ EPHYR_RETURN_VAL_IF_FAIL(a_req, BadValue);
+ EPHYR_LOG("enter\n");
+
+ if (a_do_swap) {
+ __GLX_SWAP_SHORT(&a_req->length);
+ __GLX_SWAP_INT(&a_req->context);
+ __GLX_SWAP_INT(&a_req->fbconfig);
+ __GLX_SWAP_INT(&a_req->screen);
+ __GLX_SWAP_INT(&a_req->renderType);
+ __GLX_SWAP_INT(&a_req->shareList);
+ }
+
+ EPHYR_LOG("context creation requested. localid:%d, "
+ "screen:%d, fbconfig:%d, renderType:%d, direct:%d\n",
+ (int) a_req->context, (int) a_req->screen,
+ (int) a_req->fbconfig, (int) a_req->renderType,
+ (int) a_req->isDirect);
+
+ if (!ephyrHostGLXCreateContext(a_req->screen,
+ a_req->fbconfig,
+ a_req->context,
+ a_req->shareList, a_req->renderType,
+ a_req->isDirect, X_GLXCreateNewContext)) {
+ EPHYR_LOG_ERROR("ephyrHostGLXCreateNewContext() failed\n");
+ goto out;
+ }
+ res = Success;
+ out:
+ EPHYR_LOG("leave\n");
+ return res;
+}
+
int
ephyrGLXCreateContext(__GLXclientState * cl, GLbyte * pc)
{
@@ -485,6 +530,22 @@ ephyrGLXCreateContextSwap(__GLXclientState * cl, GLbyte * pc)
return ephyrGLXCreateContextReal(req, TRUE);
}
+int
+ephyrGLXCreateNewContext(__GLXclientState * cl, GLbyte * pc)
+{
+ xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc;
+
+ return ephyrGLXCreateNewContextReal(req, FALSE);
+}
+
+int
+ephyrGLXCreateNewContextSwap(__GLXclientState * cl, GLbyte * pc)
+{
+ xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc;
+
+ return ephyrGLXCreateNewContextReal(req, TRUE);
+}
+
static int
ephyrGLXDestroyContextReal(__GLXclientState * a_cl,
GLbyte * a_pc, Bool a_do_swap)
diff --git a/hw/kdrive/ephyr/ephyrhostglx.c b/hw/kdrive/ephyr/ephyrhostglx.c
index b1f729a1f..392489a00 100644
--- a/hw/kdrive/ephyr/ephyrhostglx.c
+++ b/hw/kdrive/ephyr/ephyrhostglx.c
@@ -439,17 +439,20 @@ ephyrHostGLXSendClientInfo(int32_t a_major, int32_t a_minor,
Bool
ephyrHostGLXCreateContext(int a_screen,
- int a_visual_id,
+ int a_generic_id,
int a_context_id,
- int a_share_list_ctxt_id, Bool a_direct)
+ int a_share_list_ctxt_id,
+ int a_render_type,
+ Bool a_direct,
+ int code)
{
Bool is_ok = FALSE;
Display *dpy = hostx_get_display();
int major_opcode = 0, remote_context_id = 0;
- xGLXCreateContextReq *req;
- EPHYR_LOG("enter. screen:%d, visual:%d, contextid:%d, direct:%d\n",
- a_screen, a_visual_id, a_context_id, a_direct);
+ EPHYR_LOG("enter. screen:%d, generic_id:%d, contextid:%d, rendertype:%d, "
+ "direct:%d\n", a_screen, a_generic_id, a_context_id,
+ a_render_type, a_direct);
if (!hostx_allocate_resource_id_peer(a_context_id, &remote_context_id)) {
EPHYR_LOG_ERROR("failed to peer the context id %d host X",
@@ -464,15 +467,38 @@ ephyrHostGLXCreateContext(int a_screen,
LockDisplay(dpy);
- /* Send the glXCreateContext request */
- GetReq(GLXCreateContext, req);
- req->reqType = major_opcode;
- req->glxCode = X_GLXCreateContext;
- req->context = remote_context_id;
- req->visual = a_visual_id;
- req->screen = DefaultScreen(dpy);
- req->shareList = a_share_list_ctxt_id;
- req->isDirect = a_direct;
+ switch (code) {
+ case X_GLXCreateContext: {
+ /* Send the glXCreateContext request */
+ xGLXCreateContextReq *req;
+ GetReq(GLXCreateContext, req);
+ req->reqType = major_opcode;
+ req->glxCode = X_GLXCreateContext;
+ req->context = remote_context_id;
+ req->visual = a_generic_id;
+ req->screen = DefaultScreen(dpy);
+ req->shareList = a_share_list_ctxt_id;
+ req->isDirect = a_direct;
+ }
+
+ case X_GLXCreateNewContext: {
+ /* Send the glXCreateNewContext request */
+ xGLXCreateNewContextReq *req;
+ GetReq(GLXCreateNewContext, req);
+ req->reqType = major_opcode;
+ req->glxCode = X_GLXCreateNewContext;
+ req->context = remote_context_id;
+ req->fbconfig = a_generic_id;
+ req->screen = DefaultScreen(dpy);
+ req->renderType = a_render_type;
+ req->shareList = a_share_list_ctxt_id;
+ req->isDirect = a_direct;
+ }
+
+ default:
+ /* This should never be reached !*/
+ EPHYR_LOG("Internal error! Invalid CreateContext code!\n");
+ }
UnlockDisplay(dpy);
SyncHandle();
diff --git a/hw/kdrive/ephyr/ephyrhostglx.h b/hw/kdrive/ephyr/ephyrhostglx.h
index 9aa8bdc4e..7ff515dc2 100644
--- a/hw/kdrive/ephyr/ephyrhostglx.h
+++ b/hw/kdrive/ephyr/ephyrhostglx.h
@@ -55,9 +55,12 @@ Bool ephyrHostGLXGetMajorOpcode(int32_t * a_opcode);
Bool ephyrHostGLXSendClientInfo(int32_t a_major, int32_t a_minor,
const char *a_extension_list);
Bool ephyrHostGLXCreateContext(int a_screen,
- int a_visual_id,
+ int a_generic_id,
int a_context_id,
- int a_shared_list_ctx_id, Bool a_direct);
+ int a_share_list_ctxt_id,
+ int a_render_type,
+ Bool a_direct,
+ int code);
Bool ephyrHostDestroyContext(int a_ctxt_id);