示例#1
0
bool EGLInteropResource::map(IDirect3DSurface9* surface, GLuint tex, int w, int h, int H)
{
    D3DSURFACE_DESC dxvaDesc;
    surface->GetDesc(&dxvaDesc);
    DYGL(glBindTexture(GL_TEXTURE_2D, tex));
    const RECT src = { 0, 0, w, h};
    HRESULT ret = device9->StretchRect(surface, &src, surface9, NULL, D3DTEXF_NONE);
    if (SUCCEEDED(ret)) {
        if (query9) {
            // Flush the draw command now. Ideally, this should be done immediately before the draw call that uses the texture. Flush it once here though.
            query9->Issue(D3DISSUE_END);
            // ensure data is copied to egl surface. Solution and comment is from chromium
            // The DXVA decoder has its own device which it uses for decoding. ANGLE has its own device which we don't have access to.
            // The above code attempts to copy the decoded picture into a surface which is owned by ANGLE.
            // As there are multiple devices involved in this, the StretchRect call above is not synchronous.
            // We attempt to flush the batched operations to ensure that the picture is copied to the surface owned by ANGLE.
            // We need to do this in a loop and call flush multiple times.
            // We have seen the GetData call for flushing the command buffer fail to return success occassionally on multi core machines, leading to an infinite loop.
            // Workaround is to have an upper limit of 10 on the number of iterations to wait for the Flush to finish.
            int k = 0;
            // skip at decoder.close()
            while (/*!skip_dx.load() && */(query9->GetData(NULL, 0, D3DGETDATA_FLUSH) == FALSE) && ++k < 10) {
                Sleep(1);
            }
        }
        eglBindTexImage(egl->dpy, egl->surface, EGL_BACK_BUFFER);
    } else {
        qWarning() << "map to egl error: " << ret << " - " << qt_error_string(ret);
    }
    DYGL(glBindTexture(GL_TEXTURE_2D, 0));
    return true;
}
示例#2
0
EGLTextureFromPixmap::EGLTextureFromPixmap(const NativePixmap handle, bool hasAlpha, EGLConfig config)
    : m_eglImage(0)
    , m_surface(EGL_NO_SURFACE)
{
    if (!handle)
        return;

    static bool textureFromPixmapSupported = GLPlatformContext::supportsEGLExtension(EGLHelper::eglDisplay(), "EGL_NOK_texture_from_pixmap");

    if (textureFromPixmapSupported) {
        const EGLint pixmapAttribs[] = { EGL_TEXTURE_FORMAT, hasAlpha ? EGL_TEXTURE_RGBA : EGL_TEXTURE_RGB, EGL_TEXTURE_TARGET, EGL_TEXTURE_2D, EGL_NONE };
        m_surface = eglCreatePixmapSurface(EGLHelper::eglDisplay(), config, handle, pixmapAttribs);

        if (m_surface != EGL_NO_SURFACE && !eglBindTexImage(EGLHelper::eglDisplay(), m_surface, EGL_BACK_BUFFER))
            destroy();
    }

    if (m_surface != EGL_NO_SURFACE)
        return;

    static const EGLint imageAttrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
    EGLHelper::createEGLImage(&m_eglImage, EGL_NATIVE_PIXMAP_KHR, (EGLClientBuffer)(handle), imageAttrs);

    if (m_eglImage) {
        EGLHelper::imageTargetTexture2DOES(m_eglImage);
        EGLint error = eglGetError();

        if (error != EGL_SUCCESS)
            destroy();
    }
}
示例#3
0
bool EGLInteropResource::map(IDirect3DSurface9* surface, GLuint tex, int w, int h, int)
{
    if (!ensureSurface(w, h)) {
        releaseEGL();
        releaseDX();
        return false;
    }
    const RECT src = { 0, 0, (~0-1)&w, (~0-1)&h};
    DX_ENSURE(d3ddev->StretchRect(surface, &src, dx_surface, NULL, D3DTEXF_NONE), false);
    if (dx_query) {
        // Flush the draw command now. Ideally, this should be done immediately before the draw call that uses the texture. Flush it once here though.
        dx_query->Issue(D3DISSUE_END); //StretchRect does not supports odd values
        // ensure data is copied to egl surface. Solution and comment is from chromium
        // The DXVA decoder has its own device which it uses for decoding. ANGLE has its own device which we don't have access to.
        // The above code attempts to copy the decoded picture into a surface which is owned by ANGLE.
        // As there are multiple devices involved in this, the StretchRect call above is not synchronous.
        // We attempt to flush the batched operations to ensure that the picture is copied to the surface owned by ANGLE.
        // We need to do this in a loop and call flush multiple times.
        // We have seen the GetData call for flushing the command buffer fail to return success occassionally on multi core machines, leading to an infinite loop.
        // Workaround is to have an upper limit of 10 on the number of iterations to wait for the Flush to finish.
        int k = 0;
        while ((dx_query->GetData(NULL, 0, D3DGETDATA_FLUSH) == FALSE) && ++k < 10) {
            Sleep(1);
        }
    }
    DYGL(glBindTexture(GL_TEXTURE_2D, tex));
    eglBindTexImage(egl->dpy, egl->surface, EGL_BACK_BUFFER);
    DYGL(glBindTexture(GL_TEXTURE_2D, 0));
    return true;
}
static enum piglit_result
draw(struct egl_state *state)
{
	EGLSurface *pixmap;
	EGLint inv;
	float red[] = { 0.4, 0.0, 0.0, 1.0 };
	float purple[] = { 0.5, 0.0, 0.5, 1.0 };
	enum piglit_result result = PIGLIT_PASS;

	if (!eglGetConfigAttrib(state->egl_dpy, state->cfg,
				EGL_Y_INVERTED_NOK, &inv)) {
		fprintf(stderr,
			"eglGetConfigAttrib(EGL_Y_INVERTED_NOK) failed\n");
		return PIGLIT_FAIL;
	}
	
	printf("EGL_Y_INVERTED_NOK: %s\n", inv ? "TRUE" : "FALSE");

	pixmap = egl_util_create_pixmap(state, 100, 100, pixmap_attribs);
	if (!eglMakeCurrent(state->egl_dpy, pixmap, pixmap, state->ctx)) {
		fprintf(stderr, "eglMakeCurrent() failed\n");
		piglit_report_result(PIGLIT_FAIL);
	}
	
	/* Clear pixmap to purple */
	glClearColor(0.5, 0.0, 0.5, 1.0);
	glClear(GL_COLOR_BUFFER_BIT);

	if (!eglMakeCurrent(state->egl_dpy,
			    state->surf, state->surf, state->ctx)) {
		fprintf(stderr, "eglMakeCurrent() failed\n");
		piglit_report_result(PIGLIT_FAIL);
	}

	glViewport(0, 0, state->width, state->height);
	piglit_ortho_projection(state->width, state->height, GL_FALSE);

	glClearColor(0.4, 0.0, 0.0, 1.0);
	glClear(GL_COLOR_BUFFER_BIT);

	glEnable(GL_TEXTURE_2D);
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

	eglBindTexImage(state->egl_dpy, pixmap, EGL_BACK_BUFFER);
	piglit_draw_rect_tex(20, 20, 100, 100,  0, 0, 1, 1);

	if (!piglit_probe_pixel_rgba(10, 10, red) ||
	    !piglit_probe_pixel_rgba(50, 10, red) ||
	    !piglit_probe_pixel_rgba(10, 50, red) ||
	    !piglit_probe_pixel_rgba(50, 50, purple) ||
	    !piglit_probe_pixel_rgba(110, 110, purple) ||
	    !piglit_probe_pixel_rgba(130, 130, red))
		result = PIGLIT_FAIL;

	eglSwapBuffers(state->egl_dpy, state->surf);

	return result;
}
示例#5
0
bool QGLPixelBuffer::bindToDynamicTexture(GLuint texture_id)
{
#if QGL_RENDER_TEXTURE
    Q_D(QGLPixelBuffer);
    if (d->invalid || d->textureFormat == EGL_NONE || !d->ctx)
        return false;
    glBindTexture(GL_TEXTURE_2D, texture_id);
    return eglBindTexImage(d->ctx->display(), d->ctx->surface(), EGL_BACK_BUFFER);
#else
    Q_UNUSED(texture_id);
    return false;
#endif
}
示例#6
0
bool EGLTextureFromPixmap::bindTexImage()
{
    if (m_surface != EGL_NO_SURFACE) {
        bool success = eglBindTexImage(EGLHelper::eglDisplay(), m_surface, EGL_BACK_BUFFER);
        return success;
    }

    if (m_eglImage) {
        EGLHelper::imageTargetTexture2DOES(m_eglImage);
        return true;
    }

    return false;
}
/* EGLBoolean eglBindTexImage ( EGLDisplay dpy, EGLSurface surface, EGLint buffer ) */
static jboolean
android_eglBindTexImage
  (JNIEnv *_env, jobject _this, jobject dpy, jobject surface, jint buffer) {
    EGLBoolean _returnValue = (EGLBoolean) 0;
    EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy);
    EGLSurface surface_native = (EGLSurface) fromEGLHandle(_env, eglsurfaceGetHandleID, surface);

    _returnValue = eglBindTexImage(
        (EGLDisplay)dpy_native,
        (EGLSurface)surface_native,
        (EGLint)buffer
    );
    return (jboolean)_returnValue;
}
/*  private native int _eglBindTexImage ( int display , int surface , int buffer ) ; */
KNIEXPORT KNI_RETURNTYPE_INT
Java_javax_microedition_khronos_egl_EGL10Impl__1eglBindTexImage() {

    jint display = KNI_GetParameterAsInt(1);
    jint surface = KNI_GetParameterAsInt(2);
    jint buffer = KNI_GetParameterAsInt(3);

    jint returnValue = (jint)eglBindTexImage((EGLDisplay)display,
					     (EGLSurface)surface,
					     (EGLint)buffer);
#ifdef DEBUG
    printf("eglBindTexImage(0x%x, 0x%x, %d) = %d\n",
	   display, surface, buffer, returnValue);
#endif

    KNI_ReturnInt(returnValue);
}
示例#9
0
static void
draw(void)
{
   use_pbuffer();
   draw_triangle();

   use_window();

   eglBindTexImage(dpy, surf_pbuf, EGL_BACK_BUFFER);

   glPushMatrix();
   glRotatef(view_rotx, 1, 0, 0);
   glRotatef(view_roty, 0, 1, 0);
   glRotatef(view_rotz, 0, 0, 1);

   draw_textured_cube();

   glPopMatrix();

   eglReleaseTexImage(dpy, surf_pbuf, EGL_BACK_BUFFER);
}
示例#10
0
文件: xeglgears.c 项目: aosm/X11apps
static void
texture_gears(struct egl_manager *eman, int surface_type)
{
   static const GLint verts[12] =
      { -5, -6, -10,  5, -6, -10,  -5, 4, 10,  5, 4, 10 };
   static const GLint tex_coords[8] = { 0, 0,  1, 0,  0, 1,  1, 1 };

   eglMakeCurrent(eman->dpy, eman->win, eman->win, eman->ctx);

   glClearColor(0, 0, 0, 0);
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

   glEnable(GL_TEXTURE_2D);
   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_REPEAT);
   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   
   glEnableClientState(GL_VERTEX_ARRAY);
   glEnableClientState(GL_TEXTURE_COORD_ARRAY);
   glVertexPointer(3, GL_INT, 0, verts);
   glTexCoordPointer(2, GL_INT, 0, tex_coords);

   if (surface_type == GEARS_PBUFFER_TEXTURE)
      eglBindTexImage(eman->dpy, eman->pbuf, EGL_BACK_BUFFER);

   glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

   glDisableClientState(GL_VERTEX_ARRAY);
   glDisableClientState(GL_COLOR_ARRAY);
   glDisable(GL_TEXTURE_2D);

   if (surface_type == GEARS_PBUFFER_TEXTURE)
      eglReleaseTexImage(eman->dpy, eman->pbuf, EGL_BACK_BUFFER);

   eglSwapBuffers(eman->dpy, eman->win); 
}
示例#11
0
void XCompositeEglClientBufferIntegration::bindTextureToBuffer(struct ::wl_resource *buffer)
{
    XCompositeBuffer *compositorBuffer = XCompositeBuffer::fromResource(buffer);
    Pixmap pixmap = XCompositeNameWindowPixmap(mDisplay, compositorBuffer->window());

    QVector<EGLint> eglConfigSpec = eglbuildSpec();

    EGLint matching = 0;
    EGLConfig config;
    bool matched = eglChooseConfig(mEglDisplay,eglConfigSpec.constData(),&config,1,&matching);
    if (!matched || !matching) {
        qWarning("Could not retrieve a suitable EGL config");
        return;
    }

    QVector<EGLint> attribList;

    attribList.append(EGL_TEXTURE_FORMAT);
    attribList.append(EGL_TEXTURE_RGBA);
    attribList.append(EGL_TEXTURE_TARGET);
    attribList.append(EGL_TEXTURE_2D);
    attribList.append(EGL_NONE);

    EGLSurface surface = eglCreatePixmapSurface(mEglDisplay,config,pixmap,attribList.constData());
    if (surface == EGL_NO_SURFACE) {
        qDebug() << "Failed to create eglsurface" << pixmap << compositorBuffer->window();
    }

    compositorBuffer->setInvertedY(true);

    if (!eglBindTexImage(mEglDisplay,surface,EGL_BACK_BUFFER)) {
        qDebug() << "Failed to bind";
    }

    //    eglDestroySurface(mEglDisplay,surface);
}
示例#12
0
// Test creating a pbuffer from a d3d surface and binding it to a texture
TEST_P(D3DTextureTest, BindTexImage)
{
    if (!valid())
    {
        return;
    }

    EGLWindow *window = getEGLWindow();
    EGLDisplay display = window->getDisplay();

    const size_t bufferSize = 32;

    EGLSurface pbuffer =
        createPBuffer(bufferSize, bufferSize, EGL_TEXTURE_RGBA, EGL_TEXTURE_2D, 1, 0);
    ASSERT_EGL_SUCCESS();
    ASSERT_NE(pbuffer, EGL_NO_SURFACE);

    // Apply the Pbuffer and clear it to purple
    eglMakeCurrent(display, pbuffer, pbuffer, window->getContext());
    ASSERT_EGL_SUCCESS();

    glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize));
    glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    ASSERT_GL_NO_ERROR();

    EXPECT_PIXEL_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2, 255, 0,
                    255, 255);

    // Apply the window surface
    eglMakeCurrent(display, window->getSurface(), window->getSurface(), window->getContext());

    // Create a texture and bind the Pbuffer to it
    GLuint texture = 0;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    EXPECT_GL_NO_ERROR();

    eglBindTexImage(display, pbuffer, EGL_BACK_BUFFER);
    glViewport(0, 0, getWindowWidth(), getWindowHeight());
    ASSERT_EGL_SUCCESS();

    // Draw a quad and verify that it is purple
    glUseProgram(mTextureProgram);
    glUniform1i(mTextureUniformLocation, 0);

    drawQuad(mTextureProgram, "position", 0.5f);
    EXPECT_GL_NO_ERROR();

    // Unbind the texture
    eglReleaseTexImage(display, pbuffer, EGL_BACK_BUFFER);
    ASSERT_EGL_SUCCESS();

    // Verify that purple was drawn
    EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 255, 0, 255, 255);

    glDeleteTextures(1, &texture);

    // Make current with fixture EGL to ensure the Surface can be released immediately.
    getEGLWindow()->makeCurrent();
    eglDestroySurface(display, pbuffer);
}
示例#13
0
QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmap *pixmap, const qint64 key,
                                                           QGLContext::BindOptions options)
{
    Q_Q(QGLContext);

    // The EGL texture_from_pixmap has no facility to invert the y coordinate
    if (!(options & QGLContext::CanFlipNativePixmapBindOption))
        return 0;


    static bool checkedForTFP = false;
    static bool haveTFP = false;
    static bool checkedForEglImageTFP = false;
    static bool haveEglImageTFP = false;


    if (!checkedForEglImageTFP) {
        checkedForEglImageTFP = true;

        // We need to be able to create an EGLImage from a native pixmap, which was split
        // into a separate EGL extension, EGL_KHR_image_pixmap. It is possible to have
        // eglCreateImageKHR & eglDestroyImageKHR without support for pixmaps, so we must
        // check we have the EGLImage from pixmap functionality.
        if (QEgl::hasExtension("EGL_KHR_image") || QEgl::hasExtension("EGL_KHR_image_pixmap")) {

            // Being able to create an EGLImage from a native pixmap is also pretty useless
            // without the ability to bind that EGLImage as a texture, which is provided by
            // the GL_OES_EGL_image extension, which we try to resolve here:
            haveEglImageTFP = qt_resolve_eglimage_gl_extensions(q);

            if (haveEglImageTFP)
                qDebug("Found EGL_KHR_image_pixmap & GL_OES_EGL_image extensions (preferred method)!");
        }
    }

    if (!checkedForTFP) {
        // Check for texture_from_pixmap egl extension
        checkedForTFP = true;
        if (QEgl::hasExtension("EGL_NOKIA_texture_from_pixmap") ||
            QEgl::hasExtension("EGL_EXT_texture_from_pixmap"))
        {
            qDebug("Found texture_from_pixmap EGL extension!");
            haveTFP = true;
        }
    }

    if (!haveTFP && !haveEglImageTFP)
        return 0;


    QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pixmap->data_ptr().data());
    Q_ASSERT(pixmapData->classId() == QPixmapData::X11Class);
    bool hasAlpha = pixmapData->hasAlphaChannel();
    bool pixmapHasValidSurface = false;
    bool textureIsBound = false;
    GLuint textureId;
    glGenTextures(1, &textureId);
    glBindTexture(GL_TEXTURE_2D, textureId);

    if (haveTFP && pixmapData->gl_surface &&
        hasAlpha == (pixmapData->flags & QX11PixmapData::GlSurfaceCreatedWithAlpha))
    {
        pixmapHasValidSurface = true;
    }

    // If we already have a valid EGL surface for the pixmap, we should use it
    if (pixmapHasValidSurface) {
        EGLBoolean success;
        success = eglBindTexImage(QEgl::display(), (EGLSurface)pixmapData->gl_surface, EGL_BACK_BUFFER);
        if (success == EGL_FALSE) {
            qWarning() << "eglBindTexImage() failed:" << QEgl::errorString();
            eglDestroySurface(QEgl::display(), (EGLSurface)pixmapData->gl_surface);
            pixmapData->gl_surface = (void*)EGL_NO_SURFACE;
        } else
            textureIsBound = true;
    }

    // If the pixmap doesn't already have a valid surface, try binding it via EGLImage
    // first, as going through EGLImage should be faster and better supported:
    if (!textureIsBound && haveEglImageTFP) {
        EGLImageKHR eglImage;

        EGLint attribs[] = {
            EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
            EGL_NONE
        };
        eglImage = QEgl::eglCreateImageKHR(QEgl::display(), EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR,
                                     (EGLClientBuffer)QEgl::nativePixmap(pixmap), attribs);

        QGLContext* ctx = q;
        glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, eglImage);

        GLint err = glGetError();
        if (err == GL_NO_ERROR)
            textureIsBound = true;

        // Once the egl image is bound, the texture becomes a new sibling image and we can safely
        // destroy the EGLImage we created for the pixmap:
        if (eglImage != EGL_NO_IMAGE_KHR)
            QEgl::eglDestroyImageKHR(QEgl::display(), eglImage);
    }

    if (!textureIsBound && haveTFP) {
        // Check to see if the surface is still valid
        if (pixmapData->gl_surface &&
            hasAlpha != (pixmapData->flags & QX11PixmapData::GlSurfaceCreatedWithAlpha))
        {
            // Surface is invalid!
            destroyGlSurfaceForPixmap(pixmapData);
        }

        if (pixmapData->gl_surface == 0) {
            EGLConfig config = QEgl::defaultConfig(QInternal::Pixmap,
                                                   QEgl::OpenGL,
                                                   hasAlpha ? QEgl::Translucent : QEgl::NoOptions);

            pixmapData->gl_surface = (void*)QEgl::createSurface(pixmap, config);
            if (pixmapData->gl_surface == (void*)EGL_NO_SURFACE)
                return false;
        }

        EGLBoolean success;
        success = eglBindTexImage(QEgl::display(), (EGLSurface)pixmapData->gl_surface, EGL_BACK_BUFFER);
        if (success == EGL_FALSE) {
            qWarning() << "eglBindTexImage() failed:" << QEgl::errorString();
            eglDestroySurface(QEgl::display(), (EGLSurface)pixmapData->gl_surface);
            pixmapData->gl_surface = (void*)EGL_NO_SURFACE;
            haveTFP = false; // If TFP isn't working, disable it's use
        } else
            textureIsBound = true;
    }

    QGLTexture *texture = 0;

    if (textureIsBound) {
        texture = new QGLTexture(q, textureId, GL_TEXTURE_2D, options);
        pixmapData->flags |= QX11PixmapData::InvertedWhenBoundToTexture;

        // We assume the cost of bound pixmaps is zero
        QGLTextureCache::instance()->insert(q, key, texture, 0);

        glBindTexture(GL_TEXTURE_2D, textureId);
    } else
        glDeleteTextures(1, &textureId);

    return texture;
}