// Helper function
EGLenum currentEglApi()
{
    EGLenum api = 0;
    if (EGL_NO_CONTEXT != eglGetCurrentContext())
        api = eglQueryAPI();
    return api;
}
示例#2
0
/**
 * Initialize the given _EGLContext object to defaults and/or the values
 * in the attrib_list.
 */
EGLBoolean
_eglInitContext(_EGLContext *ctx, _EGLDisplay *dpy, _EGLConfig *conf,
                const EGLint *attrib_list)
{
   const EGLenum api = eglQueryAPI();
   EGLint err;

   if (api == EGL_NONE) {
      _eglError(EGL_BAD_MATCH, "eglCreateContext(no client API)");
      return EGL_FALSE;
   }

   _eglInitResource(&ctx->Resource, sizeof(*ctx), dpy);
   ctx->ClientAPI = api;
   ctx->Config = conf;
   ctx->WindowRenderBuffer = EGL_NONE;

   ctx->ClientVersion = 1; /* the default, per EGL spec */

   err = _eglParseContextAttribList(ctx, attrib_list);
   if (err == EGL_SUCCESS && ctx->Config) {
      EGLint api_bit;

      api_bit = _eglGetContextAPIBit(ctx);
      if (!(ctx->Config->RenderableType & api_bit)) {
         _eglLog(_EGL_DEBUG, "context api is 0x%x while config supports 0x%x",
               api_bit, ctx->Config->RenderableType);
         err = EGL_BAD_CONFIG;
      }
   }
   if (err != EGL_SUCCESS)
      return _eglError(err, "eglCreateContext");

   return EGL_TRUE;
}
/* EGLenum eglQueryAPI ( void ) */
static jint
android_eglQueryAPI
  (JNIEnv *_env, jobject _this) {
    EGLenum _returnValue = (EGLenum) 0;
    _returnValue = eglQueryAPI();
    return (jint)_returnValue;
}
示例#4
0
/**
 * Initialize the given _EGLContext object to defaults and/or the values
 * in the attrib_list.
 */
EGLBoolean
_eglInitContext(_EGLContext *ctx, _EGLDisplay *dpy, _EGLConfig *conf,
                const EGLint *attrib_list)
{
   const EGLenum api = eglQueryAPI();
   EGLint err;

   if (api == EGL_NONE) {
      _eglError(EGL_BAD_MATCH, "eglCreateContext(no client API)");
      return EGL_FALSE;
   }

   memset(ctx, 0, sizeof(_EGLContext));
   ctx->Resource.Display = dpy;
   ctx->ClientAPI = api;
   ctx->Config = conf;
   ctx->WindowRenderBuffer = EGL_NONE;

   ctx->ClientVersion = 1; /* the default, per EGL spec */

   err = _eglParseContextAttribList(ctx, attrib_list);
   if (err != EGL_SUCCESS)
      return _eglError(err, "eglCreateContext");

   return EGL_TRUE;
}
示例#5
0
EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL(void)
{
	EGLenum api = eglQueryAPI();
	eglBindAPI(EGL_OPENGL_ES_API);
	eglWaitClient();
	eglBindAPI(api);

	return EGL_TRUE;
}
示例#6
0
文件: dri3.c 项目: sarnex/wine
/* hypothesis: at this step all textures, etc are destroyed */
void
DRI2FallbackDestroy(struct DRI2priv *priv)
{
    EGLenum current_api;
    current_api = eglQueryAPI();
    eglBindAPI(EGL_OPENGL_API);
    eglMakeCurrent(priv->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    eglDestroyContext(priv->display, priv->context);
    eglTerminate(priv->display);
    eglBindAPI(current_api);
    free(priv);
}
void WindowSurfaceImpl::saveEglState()
{
    // Some painter needs to be active on the device
    // in order to get correct data from EGL, so if 
    // there's no active painter, activate one here
    if(!mMainSurface.device->paintingActive())
    {
        mPainter.begin(mMainSurface.device);
    }
    mEgl.drawSurface = eglGetCurrentSurface(EGL_DRAW);
    mEgl.readSurface = eglGetCurrentSurface(EGL_READ);
    mEgl.display = eglGetCurrentDisplay();
    mEgl.context = eglGetCurrentContext();
    mEgl.api = eglQueryAPI();
}
示例#8
0
Context *
createContext(const Visual *_visual, Context *shareContext, Profile profile, bool debug)
{
    const EglVisual *visual = static_cast<const EglVisual *>(_visual);
    EGLContext share_context = EGL_NO_CONTEXT;
    EGLContext context;
    Attributes<EGLint> attribs;

    if (shareContext) {
        share_context = static_cast<EglContext*>(shareContext)->context;
    }

    EGLint api = eglQueryAPI();

    switch (profile) {
    case PROFILE_COMPAT:
        load("libGL.so.1");
        eglBindAPI(EGL_OPENGL_API);
        break;
    case PROFILE_CORE:
        assert(0);
        return NULL;
    case PROFILE_ES1:
        load("libGLESv1_CM.so.1");
        eglBindAPI(EGL_OPENGL_ES_API);
        break;
    case PROFILE_ES2:
        load("libGLESv2.so.2");
        eglBindAPI(EGL_OPENGL_ES_API);
        attribs.add(EGL_CONTEXT_CLIENT_VERSION, 2);
        break;
    default:
        return NULL;
    }

    attribs.end(EGL_NONE);

    context = eglCreateContext(eglDisplay, visual->config, share_context, attribs);
    if (!context)
        return NULL;

    eglBindAPI(api);

    return new EglContext(visual, profile, context);
}
示例#9
0
/**
 * Initialize the given _EGLContext object to defaults and/or the values
 * in the attrib_list.
 */
EGLBoolean
_eglInitContext(_EGLContext *ctx, _EGLDisplay *dpy, _EGLConfig *conf,
                const EGLint *attrib_list)
{
   const EGLenum api = eglQueryAPI();
   EGLint err;

   if (api == EGL_NONE) {
      _eglError(EGL_BAD_MATCH, "eglCreateContext(no client API)");
      return EGL_FALSE;
   }

   memset(ctx, 0, sizeof(_EGLContext));
   _eglInitResource(&ctx->Resource, sizeof(_EGLResource), dpy);
   ctx->ClientAPI = api;
   ctx->Config = conf;
   ctx->WindowRenderBuffer = EGL_NONE;
   ctx->Profile = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR;

   ctx->ClientMajorVersion = 1; /* the default, per EGL spec */
   ctx->ClientMinorVersion = 0;
   ctx->Flags = 0;
   ctx->Profile = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR;
   ctx->ResetNotificationStrategy = EGL_NO_RESET_NOTIFICATION_KHR;

   err = _eglParseContextAttribList(ctx, dpy, attrib_list);
   if (err == EGL_SUCCESS && ctx->Config) {
      EGLint api_bit;

      api_bit = _eglGetContextAPIBit(ctx);
      if (!(ctx->Config->RenderableType & api_bit)) {
         _eglLog(_EGL_DEBUG, "context api is 0x%x while config supports 0x%x",
               api_bit, ctx->Config->RenderableType);
         err = EGL_BAD_CONFIG;
      }
   }
   if (err != EGL_SUCCESS)
      return _eglError(err, "eglCreateContext");

   return EGL_TRUE;
}
示例#10
0
文件: dri3.c 项目: sarnex/wine
/* Destroy the content, except the link and the struct mem */
static void
PRESENTDestroyPixmapContent(Display *dpy, PRESENTPixmapPriv *present_pixmap)
{
    XFreePixmap(dpy, present_pixmap->pixmap);
#ifdef D3DADAPTER9_DRI2
    if (present_pixmap->dri2_info.is_dri2) {
        struct DRI2priv *dri2_priv = present_pixmap->dri2_info.dri2_priv;
        EGLenum current_api;
        current_api = eglQueryAPI();
        eglBindAPI(EGL_OPENGL_API);
        if(eglMakeCurrent(dri2_priv->display, EGL_NO_SURFACE, EGL_NO_SURFACE, dri2_priv->context)) {
            glDeleteFramebuffers(1, &present_pixmap->dri2_info.fbo_read);
            glDeleteFramebuffers(1, &present_pixmap->dri2_info.fbo_write);
            glDeleteTextures(1, &present_pixmap->dri2_info.texture_read);
            glDeleteTextures(1, &present_pixmap->dri2_info.texture_write);
        } else {
            ERR("eglMakeCurrent failed with 0x%0X\n", eglGetError());
        }
        eglMakeCurrent(dri2_priv->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
        eglBindAPI(current_api);
    }
#endif
}
示例#11
0
/**
 * Initialize the given _EGLContext object to defaults and/or the values
 * in the attrib_list.
 */
EGLBoolean
_eglInitContext(_EGLDriver *drv, _EGLContext *ctx,
                _EGLConfig *conf, const EGLint *attrib_list)
{
   EGLint i;
   const EGLenum api = eglQueryAPI();

   if (api == EGL_NONE) {
      _eglError(EGL_BAD_MATCH, "eglCreateContext(no client API)");
      return EGL_FALSE;
   }

   memset(ctx, 0, sizeof(_EGLContext));

   ctx->ClientVersion = 1; /* the default, per EGL spec */

   for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
      switch (attrib_list[i]) {
      case EGL_CONTEXT_CLIENT_VERSION:
         i++;
         ctx->ClientVersion = attrib_list[i];
         break;
      default:
         _eglError(EGL_BAD_ATTRIBUTE, "_eglInitContext");
         return EGL_FALSE;
      }
   }

   ctx->Config = conf;
   ctx->DrawSurface = EGL_NO_SURFACE;
   ctx->ReadSurface = EGL_NO_SURFACE;
   ctx->ClientAPI = api;
   ctx->WindowRenderBuffer = EGL_NONE;

   return EGL_TRUE;
}
JNIEXPORT jint JNICALL Java_org_lwjgl_opengles_EGL_eglQueryAPI(JNIEnv *env, jclass clazz) {
    return eglQueryAPI();
}
示例#13
0
/*!***********************************************************************
@Function		ApiScreenCaptureBuffer
@Input			Width Width of the region to capture
@Input			Height Height of the region to capture
@Input			pBuf A buffer to put the screen capture into
@description	API-specific function to store the current content of the
				FrameBuffer into the memory allocated by the user.
*************************************************************************/
bool PVRShellInit::ApiScreenCaptureBuffer(int Width,int Height,unsigned char *pBuf)
{
	unsigned char	*pLines2;
	int				i, j;
	bool			bRet = true;


#ifdef BUILD_OVG
	if(eglQueryAPI() != EGL_OPENVG_API)
	{
		m_pShell->PVRShellOutputDebug("PVRShell: Screen capture failed. OpenVG is not the current API");
		return false;
	}
#endif

	/* Allocate memory for line */
	pLines2 = (unsigned char *)calloc(4 * Width * Height, sizeof(unsigned char));
	if (!pLines2) return false;

#ifdef BUILD_OVG
	while (vgGetError());

	vgReadPixels(pLines2, Width * 4, VG_sRGBA_8888, 0, 0, Width, Height);

	if(vgGetError())
	{
		bRet = false;
	}
	else
	{
		/* Convert RGB to BGR in line */
		for (j = 0, i = 0; j < 4 * Width * Height; j += 4, i += 3)
		{
			pBuf[i]   = pLines2[j+1];
			pBuf[i+1] = pLines2[j+2];
			pBuf[i+2] = pLines2[j+3];
		}
	}
#else
	while (glGetError());
	/* Read line from frame buffer */
	glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, pLines2);

	if(glGetError())
	{
		bRet = false;
	}
	else
	{
		/* Convert RGB to BGR in line */
		for (j = 0, i = 0; j < 4 * Width * Height; j += 4, i += 3)
		{
			pBuf[i] = pLines2[j+2];
			pBuf[i+1] = pLines2[j+1];
			pBuf[i+2] = pLines2[j];
		}
	}
#endif

	free(pLines2);
	return bRet;
}
示例#14
0
int ngi_context_egl_init(ngi_context* ctx, ngi_window* win) {

    EGLNativeDisplayType ndpy = NULL;
    
    EGLNativeWindowType nwnd = 0;
    
    #ifdef NGI_WINDOW_XLIB
    if(win->app->type == ngi_wm_api_xlib ) {
        ndpy = (EGLNativeDisplayType)win->app->plat.xlib.dpy;
        nwnd = (EGLNativeWindowType)win->plat.xlib.win;
    }
    #endif

    ctx->type = ngi_context_api_egl;
    EGLDisplay edpy = ctx->platform.egl.edpy = eglGetDisplay( ndpy );
    EGLint majorVersion, minorVersion;
    int succ;

    EGLConfig ecfg;
    EGLint num_config;
    EGLContext ectxt;
    EGLSurface esfc;

    EGLint ctxattr[] = { 
        EGL_CONTEXT_CLIENT_VERSION, 2, 
        
        EGL_NONE 
        
        };

    EGLint attr[] = {
 /*       EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT | EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT,*/
/*        EGL_NATIVE_RENDERABLE, 1,*/
/*        EGL_CONFIG_CAVEAT, EGL_NONE,*/
        EGL_NONE
    };
    
    
    printf("eglGetDisplay: %p\n", edpy);
    checkEGL();
    succ = eglInitialize(edpy, &majorVersion, &minorVersion);
    printf("eglInitialize: %d\n", succ);
    checkEGL();

//    eglBindAPI(EGL_OPENGL_API);

    const char* apis = eglQueryString(edpy, EGL_CLIENT_APIS);
    const char* exts = eglQueryString(edpy, EGL_EXTENSIONS);
        
    printf("EGL APIs: %s\n", apis);
    printf("EGL Extensions: %s\n", exts);

    
    if(!eglChooseConfig(edpy, attr, &ecfg, 1, &num_config)) {
        printf("eglChooseConfig error\n");
        return 0;
    }
    if(num_config != 1) {
        printf("More than one config: %d\n", num_config);
        return 0;
    }

    checkEGL();

    esfc = ctx->platform.egl.esfc = eglCreateWindowSurface(edpy, ecfg, nwnd, NULL);
    if(esfc == EGL_NO_SURFACE) {
        printf("Unable to create EGL surface (%x)\n", eglGetError());
        return 0;
    }
    ectxt = ctx->platform.egl.ectx = eglCreateContext(edpy, ecfg, EGL_NO_CONTEXT, ctxattr);
    if(ectxt == EGL_NO_CONTEXT) {
        printf("Unable to create EGL context (%x)\n", eglGetError());
        return 0;
    }
    eglMakeCurrent(edpy, esfc, esfc, ectxt);
    
    checkEGL();

    EGLint val = 0;
    eglQueryContext(edpy, ectxt, EGL_CONTEXT_CLIENT_TYPE, &val);
    printf("Context client type: %x\n", val);
    eglQueryContext(edpy, ectxt, EGL_CONTEXT_CLIENT_VERSION, &val);
    printf("Context client version: %d\n", val);

    EGLenum api = eglQueryAPI();
    int ver=0;

    switch(api) {
        case EGL_OPENGL_ES_API:
        eglQueryContext(edpy, ectxt, EGL_CONTEXT_CLIENT_VERSION, &ver);
        switch(ver) {
            case 1: ctx->graphics = ngi_graphics_api_gles1; break;
            case 2: ctx->graphics = ngi_graphics_api_gles2; break;
            default: printf("Unsupported GLES version %d\n", ver);
        }
        break;
        case EGL_OPENGL_API:
        ctx->graphics = ngi_graphics_api_opengl;
        break;
        default:
        printf("Unsupported EGL Graphics api 0x%x\n", api);
    }

    eglSwapInterval(edpy,1);

    win->context = ctx;

    return 1;
}
//--------------------------------------------------------------------------------------
// Name: WndProc()
// Desc: The application window's message proc
//--------------------------------------------------------------------------------------
LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
    // Get the application data
    CFrmAppContainer* pAppContainer = (CFrmAppContainer*)GetWindowLong( hWnd, GWL_USERDATA );

    switch( uMsg )
    {
	case WM_SETCURSOR:
            // User has tapped the screen
            PostQuitMessage( 0 );
            break;

        case WM_KEYDOWN:
        case WM_KEYUP:
        {
            // Ignore redundant messages from automatically repeated keystrokes
            if( ( uMsg == WM_KEYDOWN ) && ( HIWORD(lParam) & KF_REPEAT ) )
                return 0;

            BOOL bShiftKeyState = ( GetKeyState( VK_SHIFT )   & 0x8000 ) ? TRUE : FALSE;
            BOOL bCtrlKeyState  = ( GetKeyState( VK_CONTROL ) & 0x8000 ) ? TRUE : FALSE;

            // Handle the ESC key
            if( wParam == VK_ESCAPE )
            {
                PostQuitMessage( 0 );
                return 0;
            }

            // Handle remaining keys
            // Note: some mappings may only apply to US keyboards
            UINT32 nButtonMask = 0;
            switch( wParam )
            {
                case '1':         nButtonMask = bShiftKeyState ? FRM_INPUT::NONE     : FRM_INPUT::KEY_1; break;
                case '2':         nButtonMask = bShiftKeyState ? FRM_INPUT::NONE     : FRM_INPUT::KEY_2; break;
                case '3':         nButtonMask = bShiftKeyState ? FRM_INPUT::KEY_HASH : FRM_INPUT::KEY_3; break;
                case '4':         nButtonMask = bShiftKeyState ? FRM_INPUT::NONE     : FRM_INPUT::KEY_4; break;
                case '5':         nButtonMask = bShiftKeyState ? FRM_INPUT::NONE     : FRM_INPUT::KEY_5; break;
                case '6':         nButtonMask = bShiftKeyState ? FRM_INPUT::NONE     : FRM_INPUT::KEY_6; break;
                case '7':         nButtonMask = bShiftKeyState ? FRM_INPUT::NONE     : FRM_INPUT::KEY_7; break;
                case '8':         nButtonMask = bShiftKeyState ? FRM_INPUT::KEY_STAR : FRM_INPUT::KEY_8; break;
                case '9':         nButtonMask = bShiftKeyState ? FRM_INPUT::NONE     : FRM_INPUT::KEY_9; break;
                case '0':         nButtonMask = bShiftKeyState ? FRM_INPUT::NONE     : FRM_INPUT::KEY_0; break;
                case VK_NUMPAD1:  nButtonMask = FRM_INPUT::KEY_1; break;
                case VK_NUMPAD2:  nButtonMask = FRM_INPUT::KEY_2; break;
                case VK_NUMPAD3:  nButtonMask = FRM_INPUT::KEY_3; break;
                case VK_NUMPAD4:  nButtonMask = FRM_INPUT::KEY_4; break;
                case VK_NUMPAD5:  nButtonMask = FRM_INPUT::KEY_5; break;
                case VK_NUMPAD6:  nButtonMask = FRM_INPUT::KEY_6; break;
                case VK_NUMPAD7:  nButtonMask = FRM_INPUT::KEY_7; break;
                case VK_NUMPAD8:  nButtonMask = FRM_INPUT::KEY_8; break;
                case VK_NUMPAD9:  nButtonMask = FRM_INPUT::KEY_9; break;
                case VK_NUMPAD0:  nButtonMask = FRM_INPUT::KEY_0; break;
                case VK_MULTIPLY: nButtonMask = FRM_INPUT::KEY_STAR;   break;
                case VK_LEFT:     nButtonMask = FRM_INPUT::DPAD_LEFT;  break;
                case VK_RIGHT:    nButtonMask = FRM_INPUT::DPAD_RIGHT; break;
                case VK_UP:       nButtonMask = FRM_INPUT::DPAD_UP;    break;
                case VK_DOWN:     nButtonMask = FRM_INPUT::DPAD_DOWN;  break;
                case VK_SPACE:    nButtonMask = FRM_INPUT::SELECT;     break;
                case VK_RETURN:   nButtonMask = FRM_INPUT::SELECT;     break;
                case VK_BACK:     nButtonMask = FRM_INPUT::KEY_CLEAR;  break;
                case VK_DELETE:   nButtonMask = FRM_INPUT::KEY_CLEAR;  break;
                case VK_INSERT:   nButtonMask = FRM_INPUT::KEY_EDIT;   break;
            }

            if( nButtonMask )
            {
                if( uMsg == WM_KEYDOWN )
                    pAppContainer->m_pApplication->m_Input.m_nButtons |= nButtonMask;
                else
                    pAppContainer->m_pApplication->m_Input.m_nButtons &= ~nButtonMask;
            }

            // Toggle the window orientation between portrait and landscape mode
            EGLenum nAPI = eglQueryAPI();
            if( nAPI == EGL_OPENGL_ES_API && uMsg == WM_KEYDOWN && nButtonMask == FRM_INPUT::KEY_STAR )
                pAppContainer->ToggleOrientation();

            return 0;
        }

        case WM_DESTROY:
        case WM_CLOSE:
            PostQuitMessage( 0 );
            return 0;
    }

    // Pass all unhandled messages to the default WndProc
    return DefWindowProc( hWnd, uMsg, wParam, lParam );
}
示例#16
0
文件: dri3.c 项目: sarnex/wine
BOOL
DRI2FallbackPRESENTPixmap(PRESENTpriv *present_priv, struct DRI2priv *dri2_priv,
                          int fd, int width, int height, int stride, int depth,
                          int bpp, PRESENTPixmapPriv **present_pixmap_priv)
{
    Window root = RootWindow(dri2_priv->dpy, DefaultScreen(dri2_priv->dpy));
    Pixmap pixmap;
    EGLImageKHR image;
    GLuint texture_read, texture_write, fbo_read, fbo_write;
    EGLint attribs[] = {
        EGL_WIDTH, 0,
        EGL_HEIGHT, 0,
        EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888,
        EGL_DMA_BUF_PLANE0_FD_EXT, 0,
        EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0,
        EGL_DMA_BUF_PLANE0_PITCH_EXT, 0,
        EGL_NONE
    };
    EGLenum current_api = 0;
    int status;

    pthread_mutex_lock(&present_priv->mutex_present);

    pixmap = XCreatePixmap(dri2_priv->dpy, root, width, height, 24);
    if (!pixmap)
        goto fail;

    attribs[1] = width;
    attribs[3] = height;
    attribs[7] = fd;
    attribs[11] = stride;

    current_api = eglQueryAPI();
    eglBindAPI(EGL_OPENGL_API);

    /* We bind the dma-buf to a EGLImage, then to a texture, and then to a fbo.
     * Note that we can delete the EGLImage, but we shouldn't delete the texture,
     * else the fbo is invalid */

    image = dri2_priv->eglCreateImageKHR_func(dri2_priv->display,
                              EGL_NO_CONTEXT,
                              EGL_LINUX_DMA_BUF_EXT,
                              NULL, attribs);

    if (image == EGL_NO_IMAGE_KHR)
        goto fail;
    close(fd);

    if(eglMakeCurrent(dri2_priv->display, EGL_NO_SURFACE, EGL_NO_SURFACE, dri2_priv->context)) {
        glGenTextures(1, &texture_read);
        glBindTexture(GL_TEXTURE_2D, texture_read);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        dri2_priv->glEGLImageTargetTexture2DOES_func(GL_TEXTURE_2D, image);
        glGenFramebuffers(1, &fbo_read);
        glBindFramebuffer(GL_FRAMEBUFFER, fbo_read);
        glFramebufferTexture2D(GL_FRAMEBUFFER,
                               GL_COLOR_ATTACHMENT0,
                               GL_TEXTURE_2D, texture_read,
                               0);
        status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
        if (status != GL_FRAMEBUFFER_COMPLETE)
            goto fail;
        glBindTexture(GL_TEXTURE_2D, 0);
        dri2_priv->eglDestroyImageKHR_func(dri2_priv->display, image);

        /* We bind a newly created pixmap (to which we want to copy the content)
         * to an EGLImage, then to a texture, then to a fbo. */
        image = dri2_priv->eglCreateImageKHR_func(dri2_priv->display,
                                                  dri2_priv->context,
                                                  EGL_NATIVE_PIXMAP_KHR,
                                                  (void *)pixmap, NULL);
        if (image == EGL_NO_IMAGE_KHR)
            goto fail;

        glGenTextures(1, &texture_write);
        glBindTexture(GL_TEXTURE_2D, texture_write);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        dri2_priv->glEGLImageTargetTexture2DOES_func(GL_TEXTURE_2D, image);
        glGenFramebuffers(1, &fbo_write);
        glBindFramebuffer(GL_FRAMEBUFFER, fbo_write);
        glFramebufferTexture2D(GL_FRAMEBUFFER,
                               GL_COLOR_ATTACHMENT0,
                               GL_TEXTURE_2D, texture_write,
                               0);
        status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
        if (status != GL_FRAMEBUFFER_COMPLETE)
            goto fail;
        glBindTexture(GL_TEXTURE_2D, 0);
        dri2_priv->eglDestroyImageKHR_func(dri2_priv->display, image);
    } else {
        ERR("eglMakeCurrent failed with 0x%0X\n", eglGetError());
    }
    eglMakeCurrent(dri2_priv->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);

    *present_pixmap_priv = (PRESENTPixmapPriv *) calloc(1, sizeof(PRESENTPixmapPriv));
    if (!*present_pixmap_priv) {
        goto fail;
    }

    (*present_pixmap_priv)->released = TRUE;
    (*present_pixmap_priv)->pixmap = pixmap;
    (*present_pixmap_priv)->present_priv = present_priv;
    (*present_pixmap_priv)->next = present_priv->first_present_priv;
    (*present_pixmap_priv)->width = width;
    (*present_pixmap_priv)->height = height;
    (*present_pixmap_priv)->depth = depth;
    (*present_pixmap_priv)->dri2_info.is_dri2 = TRUE;
    (*present_pixmap_priv)->dri2_info.dri2_priv = dri2_priv;
    (*present_pixmap_priv)->dri2_info.fbo_read = fbo_read;
    (*present_pixmap_priv)->dri2_info.fbo_write = fbo_write;
    (*present_pixmap_priv)->dri2_info.texture_read = texture_read;
    (*present_pixmap_priv)->dri2_info.texture_write = texture_write;

    present_priv->last_serial_given++;
    (*present_pixmap_priv)->serial = present_priv->last_serial_given;
    present_priv->first_present_priv = *present_pixmap_priv;

    eglBindAPI(current_api);

    pthread_mutex_unlock(&present_priv->mutex_present);
    return TRUE;
fail:
    eglMakeCurrent(dri2_priv->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    eglBindAPI(current_api);
    pthread_mutex_unlock(&present_priv->mutex_present);
    return FALSE;
}
示例#17
0
文件: dri3.c 项目: sarnex/wine
BOOL
DRI2FallbackInit(Display *dpy, struct DRI2priv **priv)
{
    PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES_func;
    PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR_func;
    PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT_func;
    PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR_func;
    EGLDisplay display;
    EGLint major, minor;
    EGLConfig config;
    EGLContext context;
    EGLint i;
    EGLBoolean b;
    EGLenum current_api = 0;
    const char *extensions;
    EGLint config_attribs[] = {
        EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
        EGL_NONE
    };
    EGLint context_compatibility_attribs[] = {
        EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR,
        EGL_NONE
    };

    current_api = eglQueryAPI();
    eglGetPlatformDisplayEXT_func = (PFNEGLGETPLATFORMDISPLAYEXTPROC) eglGetProcAddress("eglGetPlatformDisplayEXT");
    if (!eglGetPlatformDisplayEXT_func)
        return FALSE;
    display = eglGetPlatformDisplayEXT_func(EGL_PLATFORM_X11_EXT, dpy, NULL);
    if (!display)
        return FALSE;
    if (eglInitialize(display, &major, &minor) != EGL_TRUE)
        goto clean_egl_display;

    extensions = eglQueryString(display, EGL_CLIENT_APIS);
    if (!extensions || !strstr(extensions, "OpenGL"))
        goto clean_egl_display;

    extensions = eglQueryString(display, EGL_EXTENSIONS);
    if (!extensions || !strstr(extensions, "EGL_EXT_image_dma_buf_import") ||
        !strstr(extensions, "EGL_KHR_create_context") ||
        !strstr(extensions, "EGL_KHR_surfaceless_context") ||
        !strstr(extensions, "EGL_KHR_image_base"))
        goto clean_egl_display;

    if (!eglChooseConfig(display, config_attribs, &config, 1, &i))
        goto clean_egl_display;

    b = eglBindAPI(EGL_OPENGL_API);
    if (b == EGL_FALSE)
        goto clean_egl_display;
    context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_compatibility_attribs);
    if (context == EGL_NO_CONTEXT)
        goto clean_egl_display;

    glEGLImageTargetTexture2DOES_func = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) eglGetProcAddress("glEGLImageTargetTexture2DOES");
    eglCreateImageKHR_func = (PFNEGLCREATEIMAGEKHRPROC) eglGetProcAddress("eglCreateImageKHR");
    eglDestroyImageKHR_func = (PFNEGLDESTROYIMAGEKHRPROC) eglGetProcAddress("eglDestroyImageKHR");
    if (!eglCreateImageKHR_func || !glEGLImageTargetTexture2DOES_func || !eglDestroyImageKHR_func) {
        ERR("eglGetProcAddress failed !");
        goto clean_egl_display;
    }

    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);

    *priv = calloc(1, sizeof(struct DRI2priv));
    if (!*priv)
        goto clean_egl;
    (*priv)->dpy = dpy;
    (*priv)->display = display;
    (*priv)->context = context;
    (*priv)->glEGLImageTargetTexture2DOES_func = glEGLImageTargetTexture2DOES_func;
    (*priv)->eglCreateImageKHR_func = eglCreateImageKHR_func;
    (*priv)->eglDestroyImageKHR_func = eglDestroyImageKHR_func;
    eglBindAPI(current_api);
    return TRUE;

clean_egl:
clean_egl_display:
    eglTerminate(display);
    eglBindAPI(current_api);
    return FALSE;
}
示例#18
0
文件: dri3.c 项目: sarnex/wine
BOOL
PRESENTPixmap(Display *dpy, XID window,
              PRESENTPixmapPriv *present_pixmap_priv, D3DPRESENT_PARAMETERS *pPresentationParameters,
              const RECT *pSourceRect, const RECT *pDestRect, const RGNDATA *pDirtyRegion)
{
    PRESENTpriv *present_priv = present_pixmap_priv->present_priv;
#ifdef D3DADAPTER9_DRI2
    struct DRI2priv *dri2_priv = present_pixmap_priv->dri2_info.dri2_priv;
    EGLenum current_api = 0;
#endif
    xcb_void_cookie_t cookie;
    xcb_generic_error_t *error;
    int64_t target_msc, presentationInterval;
    xcb_xfixes_region_t valid, update;
    int16_t x_off, y_off;
    uint32_t options = XCB_PRESENT_OPTION_NONE;

    pthread_mutex_lock(&present_priv->mutex_present);

    if (window != present_priv->window)
        PRESENTPrivChangeWindow(present_priv, window);

    if (!window) {
        ERR("ERROR: Try to Present a pixmap on a NULL window\n");
        pthread_mutex_unlock(&present_priv->mutex_present);
        return FALSE;
    }

    PRESENTflush_events(present_priv, FALSE);
    if (!present_pixmap_priv->released || present_pixmap_priv->present_complete_pending) {
        ERR("FATAL ERROR: Trying to Present a pixmap not released\n");
        pthread_mutex_unlock(&present_priv->mutex_present);
        return FALSE;
    }
#ifdef D3DADAPTER9_DRI2
    if (present_pixmap_priv->dri2_info.is_dri2) {
        current_api = eglQueryAPI();
        eglBindAPI(EGL_OPENGL_API);
        if(eglMakeCurrent(dri2_priv->display, EGL_NO_SURFACE, EGL_NO_SURFACE, dri2_priv->context)) {
            glBindFramebuffer(GL_READ_FRAMEBUFFER, present_pixmap_priv->dri2_info.fbo_read);
            glBindFramebuffer(GL_DRAW_FRAMEBUFFER, present_pixmap_priv->dri2_info.fbo_write);

            glBlitFramebuffer(0, 0, present_pixmap_priv->width, present_pixmap_priv->height,
                              0, 0, present_pixmap_priv->width, present_pixmap_priv->height,
                              GL_COLOR_BUFFER_BIT, GL_NEAREST);
            glFlush(); /* Perhaps useless */
        } else {
            ERR("eglMakeCurrent failed with 0x%0X\n", eglGetError());
        }
        eglMakeCurrent(dri2_priv->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
        eglBindAPI(current_api);
    }
#endif
    target_msc = present_priv->last_msc;
    switch(pPresentationParameters->PresentationInterval) {
        case D3DPRESENT_INTERVAL_DEFAULT:
        case D3DPRESENT_INTERVAL_ONE:
            presentationInterval = 1;
            break;
        case D3DPRESENT_INTERVAL_TWO:
            presentationInterval = 2;
            break;
        case D3DPRESENT_INTERVAL_THREE:
            presentationInterval = 3;
            break;
        case D3DPRESENT_INTERVAL_FOUR:
            presentationInterval = 4;
            break;
        case D3DPRESENT_INTERVAL_IMMEDIATE:
        default:
            presentationInterval = 0;
            options |= XCB_PRESENT_OPTION_ASYNC;
            break;
    }
    target_msc += presentationInterval * (present_priv->pixmap_present_pending + 1);

    /* Note: PRESENT defines some way to do partial copy:
     * presentproto:
     * 'x-off' and 'y-off' define the location in the window where
     *  the 0,0 location of the pixmap will be presented. valid-area
     *  and update-area are relative to the pixmap.
     */
    if (!pSourceRect && !pDestRect && !pDirtyRegion) {
        valid = 0;
        update = 0;
        x_off = 0;
        y_off = 0;
    } else {
        xcb_rectangle_t rect_update;
        xcb_rectangle_t *rect_updates;
        int i;

        rect_update.x = 0;
        rect_update.y = 0;
        rect_update.width = present_pixmap_priv->width;
        rect_update.height = present_pixmap_priv->height;
        x_off = 0;
        y_off = 0;
        if (pSourceRect) {
            x_off = -pSourceRect->left;
            y_off = -pSourceRect->top;
            rect_update.x = pSourceRect->left;
            rect_update.y = pSourceRect->top;
            rect_update.width = pSourceRect->right - pSourceRect->left;
            rect_update.height = pSourceRect->bottom - pSourceRect->top;
        }
        if (pDestRect) {
            x_off += pDestRect->left;
            y_off += pDestRect->top;
            rect_update.width = pDestRect->right - pDestRect->left;
            rect_update.height = pDestRect->bottom - pDestRect->top;
            /* Note: the size of pDestRect and pSourceRect are supposed to be the same size
             * because the driver would have done things to assure that. */
        }
        valid = xcb_generate_id(present_priv->xcb_connection_bis);
        update = xcb_generate_id(present_priv->xcb_connection_bis);
        xcb_xfixes_create_region(present_priv->xcb_connection_bis, valid, 1, &rect_update);
        if (pDirtyRegion && pDirtyRegion->rdh.nCount) {
            rect_updates = (void *) calloc(pDirtyRegion->rdh.nCount, sizeof(xcb_rectangle_t));
            for (i = 0; i < pDirtyRegion->rdh.nCount; i++)
            {
                RECT rc;
                memcpy(&rc, pDirtyRegion->Buffer + i * sizeof(RECT), sizeof(RECT));
                rect_update.x = rc.left;
                rect_update.y = rc.top;
                rect_update.width = rc.right - rc.left;
                rect_update.height = rc.bottom - rc.top;
                memcpy(rect_updates + i * sizeof(xcb_rectangle_t), &rect_update, sizeof(xcb_rectangle_t));
            }
            xcb_xfixes_create_region(present_priv->xcb_connection_bis, update, pDirtyRegion->rdh.nCount, rect_updates);
            free(rect_updates);
        } else
            xcb_xfixes_create_region(present_priv->xcb_connection_bis, update, 1, &rect_update);
    }
    if (pPresentationParameters->SwapEffect == D3DSWAPEFFECT_COPY)
        options |= XCB_PRESENT_OPTION_COPY;
    cookie = xcb_present_pixmap_checked(present_priv->xcb_connection_bis,
                                        window,
                                        present_pixmap_priv->pixmap,
                                        present_pixmap_priv->serial,
                                        valid, update, x_off, y_off,
                                        None, None, None, options,
                                        target_msc, 0, 0, 0, NULL);
    error = xcb_request_check(present_priv->xcb_connection_bis, cookie); /* performs a flush */

    if (update)
        xcb_xfixes_destroy_region(present_priv->xcb_connection_bis, update);
    if (valid)
        xcb_xfixes_destroy_region(present_priv->xcb_connection_bis, valid);

    if (error) {
        xcb_get_geometry_cookie_t cookie_geom;
        xcb_get_geometry_reply_t *reply;

        cookie_geom = xcb_get_geometry(present_priv->xcb_connection_bis, window);
        reply = xcb_get_geometry_reply(present_priv->xcb_connection_bis, cookie_geom, NULL);

        ERR("Error using PRESENT. Here some debug info\n");
        if (!reply) {
            ERR("Error querying window info. Perhaps it doesn't exist anymore\n");
            pthread_mutex_unlock(&present_priv->mutex_present);
            return FALSE;
        }
        ERR("Pixmap: width=%d, height=%d, depth=%d\n",
            present_pixmap_priv->width, present_pixmap_priv->height,
            present_pixmap_priv->depth);
        ERR("Window: width=%d, height=%d, depth=%d, x=%d, y=%d\n",
            (int) reply->width, (int) reply->height,
            (int) reply->depth, (int) reply->x, (int) reply->y);
        ERR("Present parameter: PresentationInterval=%d, BackBufferCount=%d, Pending presentations=%d\n",
            pPresentationParameters->PresentationInterval,
            pPresentationParameters->BackBufferCount,
            present_priv->pixmap_present_pending
           );
        if (present_pixmap_priv->depth != reply->depth)
            ERR("Depths are different. PRESENT needs the pixmap and the window have same depth\n");
        free(reply);
        pthread_mutex_unlock(&present_priv->mutex_present);
        return FALSE;
    }
    present_priv->last_target = target_msc;
    present_priv->pixmap_present_pending++;
    present_pixmap_priv->present_complete_pending = TRUE;
    present_pixmap_priv->released = FALSE;
    pthread_mutex_unlock(&present_priv->mutex_present);
    return TRUE;
}