예제 #1
0
    void
    resize(int w, int h) {
        if (w == width && h == height) {
            return;
        }

        eglWaitClient();

        // We need to ensure that pending events are processed here, and XSync
        // with discard = True guarantees that, but it appears the limited
        // event processing we do so far is sufficient
        //XSync(display, True);

        Drawable::resize(w, h);

        XResizeWindow(display, window, w, h);

        // Tell the window manager to respect the requested size
        XSizeHints size_hints;
        size_hints.max_width  = size_hints.min_width  = w;
        size_hints.max_height = size_hints.min_height = h;
        size_hints.flags = PMinSize | PMaxSize;
        XSetWMNormalHints(display, window, &size_hints);

        waitForEvent(ConfigureNotify);

        eglWaitNative(EGL_CORE_NATIVE_ENGINE);
    }
예제 #2
0
 ~EglDrawable()
 {
     eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
     eglDestroySurface(eglDisplay, surface);
     eglWaitClient();
     eglWaitNative(EGL_CORE_NATIVE_ENGINE);
 }
/* EGLBoolean eglWaitClient ( void ) */
static jboolean
android_eglWaitClient
  (JNIEnv *_env, jobject _this) {
    EGLBoolean _returnValue = (EGLBoolean) 0;
    _returnValue = eglWaitClient();
    return (jboolean)_returnValue;
}
예제 #4
0
bool QX11GLWindowSurface::scroll(const QRegion &area, int dx, int dy)
{
    if (m_backBuffer.isNull())
        return false;

    Q_ASSERT(m_backBuffer.data_ptr()->classId() == QPixmapData::X11Class);

    // Make sure all GL rendering is complete before starting the scroll operation:
    QGLContext* ctx = static_cast<QX11GLPixmapData*>(m_backBuffer.data_ptr().data())->context();
    if (QGLContext::currentContext() != ctx && ctx && ctx->isValid())
        ctx->makeCurrent();
    eglWaitClient();

    if (!m_pixmapGC)
        m_pixmapGC = XCreateGC(X11->display, m_backBuffer.handle(), 0, 0);

    foreach (const QRect& rect, area.rects()) {
        XCopyArea(X11->display, m_backBuffer.handle(), m_backBuffer.handle(), m_pixmapGC,
                  rect.x(), rect.y(), rect.width(), rect.height(),
                  rect.x()+dx, rect.y()+dy);
    }

    // Make sure the scroll operation is complete before allowing GL rendering to resume
    eglWaitNative(EGL_CORE_NATIVE_ENGINE);

    return true;
}
예제 #5
0
 void show(void) {
     if (visible) {
         return;
     }
     eglWaitClient();
     eglWaitNative(EGL_CORE_NATIVE_ENGINE);
     Drawable::show();
 }
예제 #6
0
파일: egl.c 프로젝트: weimingtom/ogles4s3c
EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL(void)
{
	EGLenum api = eglQueryAPI();
	eglBindAPI(EGL_OPENGL_ES_API);
	eglWaitClient();
	eglBindAPI(api);

	return EGL_TRUE;
}
예제 #7
0
// Wait for client OpenGL/OpenVG operations to complete before
// using native rendering operations.
void QEglContext::waitClient()
{
#ifdef EGL_OPENGL_ES_API
    if (apiType == OpenGL) {
        eglBindAPI(EGL_OPENGL_ES_API);
        eglWaitClient();
    }
#else
    if (apiType == OpenGL)
        eglWaitGL();
#endif
#ifdef EGL_OPENVG_API
    if (apiType == OpenVG) {
        eglBindAPI(EGL_OPENVG_API);
        eglWaitClient();
    }
#endif
}
예제 #8
0
 void
 resize(int w, int h) {
     if (w == width && h == height) {
         return;
     }
     eglWaitClient();
     Drawable::resize(w, h);
     resizeSurface(w, h);
 }
void CEglTest_EGL_Image_Multi_Thread_Parallel::doThreadFunctionL(TInt aIdx)
	{
	INFO_PRINTF2(_L("CEglTest_EGL_Image_Multi_Thread_Parallel::doThreadFunctionL, Thread %d"),aIdx);
	GetDisplayL();
	CTestEglSession* eglSess = CTestEglSession::NewLC(Logger(), iDisplay, aIdx);
	eglSess->InitializeL();	
	eglSess->OpenSgDriverL();
	
	// create a reference bitmap (we give index 7, as there's only 1 image in this test case)
	TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat);
	CFbsBitmap* bitmap = eglSess->CreateReferenceBitmapL(bitmapMode, KPixmapSize, 7);
	CleanupStack::PushL(bitmap);

	// Create an RSgImage
	INFO_PRINTF2(_L("Thread %d, Creating a RSgImage having the reference bitmap's content"),aIdx);
	TSgImageInfoOpenVgImage imageInfo = TSgImageInfoOpenVgImage(KDefaultSourceFormat, KPixmapSize);
    RSgImage rSgImageLocal;
	CleanupClosePushL(rSgImageLocal);
	ASSERT_EQUALS(rSgImageLocal.Create(imageInfo,bitmap->DataAddress(),bitmap->DataStride()), KErrNone);

	INFO_PRINTF2(_L("Thread %d, Creating an EGLImage from the shared RSgImage"),aIdx);
	EGLImageKHR eglImageLocal = eglSess->eglCreateImageKhrL(iDisplay, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, &rSgImageLocal, KEglImageAttribsPreservedTrue);
	ASSERT_EGL_TRUE(eglImageLocal != EGL_NO_IMAGE_KHR);
	CleanupStack::PopAndDestroy(&rSgImageLocal); 	//transferring ownership of the buffer to the EGLImage
	CleanupStack::PopAndDestroy(bitmap);

	INFO_PRINTF2(_L("Thread %d, Creating a Surface and a Context bound to OpenVG"),aIdx);
	TUidPixelFormat pixelFormat = EglTestConversion::VgFormatToSgPixelFormat(KDefaultSurfaceFormat);
	TSgImageInfoOpenVgTarget imageInfo2 = TSgImageInfoOpenVgTarget(pixelFormat, KPixmapSize);
	// Create a pixmap surface matching the native image pixel format
	eglSess->CreatePixmapSurfaceAndMakeCurrentAndMatchL(imageInfo2,CTestEglSession::EResourceCloseSgImageEarly);
	
	INFO_PRINTF2(_L("Thread %d, Creating one VGImage from the EGLImage"),aIdx);
	VGImage vgImageLocal = eglSess->vgCreateImageTargetKHR((VGeglImageKHR)eglImageLocal);	
	ASSERT_VG_TRUE(vgImageLocal != VG_INVALID_HANDLE);
	ASSERT_EGL_TRUE(eglSess->DestroyEGLImage(iDisplay, eglImageLocal));
		
	// Copy the source VGImage to the surface
	vgSetPixels(0, 0, vgImageLocal, 0, 0, KPixmapSize.iWidth, KPixmapSize.iHeight);
	ASSERT_TRUE(vgGetError()==VG_NO_ERROR);
	eglWaitClient();

	// destroy VGImage
	vgDestroyImage(vgImageLocal);
	ASSERT_TRUE(vgGetError()==VG_NO_ERROR);

	// we can now compare the VgImage to the one we would expect for this particular thread
	CFbsBitmap* refBitmap = eglSess->CreateReferenceBitmapL(bitmapMode, KPixmapSize, 7);
	CleanupStack::PushL(refBitmap);
	eglSess->CheckVgDrawingL(KDefaultSurfaceFormat, refBitmap);
	CleanupStack::PopAndDestroy(refBitmap);
	INFO_PRINTF2(_L("Drawing successful, Thread %d"),aIdx);

	// cleanup
	eglSess->CloseSgDriver();
  	CleanupStack::PopAndDestroy(eglSess);	
	}
예제 #10
0
파일: qegl.cpp 프로젝트: Afreeca/qt
bool QEglContext::makeCurrent(EGLSurface surface)
{
    if (ctx == EGL_NO_CONTEXT) {
        qWarning() << "QEglContext::makeCurrent(): Cannot make invalid context current";
        return false;
    }

    if (surface == EGL_NO_SURFACE) {
        qWarning() << "QEglContext::makeCurrent(): Cannot make invalid surface current";
        return false;
    }

#ifdef Q_OS_SYMBIAN
    apiChanged = false;
    if (currentContext(apiType)
            && currentContext(apiType)->ctx != eglGetCurrentContext()) {
        // some other EGL based API active. Complete its rendering
        eglWaitClient();
        apiChanged = true;
    }
#endif

    // If lazyDoneCurrent() was called on the surface, then we may be able
    // to assume that it is still current within the thread.
    if (surface == currentSurface && currentContext(apiType) == this
            && !apiChanged) {
        current = true;
        return true;
    }

    current = true;
    currentSurface = surface;
    setCurrentContext(apiType, this);

    // Force the right API to be bound before making the context current.
    // The EGL implementation should be able to figure this out from ctx,
    // but some systems require the API to be explicitly set anyway.
#ifdef EGL_OPENGL_ES_API
    if (apiType == QEgl::OpenGL)
        eglBindAPI(EGL_OPENGL_ES_API);
#endif
#ifdef EGL_OPENVG_API
    if (apiType == QEgl::OpenVG)
        eglBindAPI(EGL_OPENVG_API);
#endif

    bool ok = eglMakeCurrent(QEgl::display(), surface, surface, ctx);
    if (!ok)
        qWarning() << "QEglContext::makeCurrent(" << surface << "):" << QEgl::errorString();
    return ok;
}
예제 #11
0
    void
    resize(int w, int h) {
        if (w == width && h == height) {
            return;
        }

        eglWaitClient();

        // We need to ensure that pending events are processed here, and XSync
        // with discard = True guarantees that, but it appears the limited
        // event processing we do so far is sufficient
        //XSync(display, True);

        Drawable::resize(w, h);

        XResizeWindow(display, window, w, h);

        // Tell the window manager to respect the requested size
        XSizeHints size_hints;
        size_hints.max_width  = size_hints.min_width  = w;
        size_hints.max_height = size_hints.min_height = h;
        size_hints.flags = PMinSize | PMaxSize;
        XSetWMNormalHints(display, window, &size_hints);

        waitForEvent(ConfigureNotify);

        eglWaitNative(EGL_CORE_NATIVE_ENGINE);

        /*
         * Some implementations won't update the backbuffer unless we recreate
         * the EGL surface.
         */

        int eglWidth;
        int eglHeight;

        eglQuerySurface(eglDisplay, surface, EGL_WIDTH, &eglWidth);
        eglQuerySurface(eglDisplay, surface, EGL_HEIGHT, &eglHeight);

        if (eglWidth != width || eglHeight != height) {
            recreate();

            eglQuerySurface(eglDisplay, surface, EGL_WIDTH, &eglWidth);
            eglQuerySurface(eglDisplay, surface, EGL_HEIGHT, &eglHeight);
        }

        assert(eglWidth == width);
        assert(eglHeight == height);
    }
예제 #12
0
    void show(void) {
        if (visible) {
            return;
        }

        eglWaitClient();

        XMapWindow(display, window);

        waitForEvent(MapNotify);

        eglWaitNative(EGL_CORE_NATIVE_ENGINE);

        Drawable::show();
    }
예제 #13
0
EGLBoolean EGLAPIENTRY
eglWaitGL(void)
{
   _EGLThreadInfo *t = _eglGetCurrentThread();
   EGLint api_index = t->CurrentAPIIndex;
   EGLint es_index = _eglConvertApiToIndex(EGL_OPENGL_ES_API);
   EGLBoolean ret;

   if (api_index != es_index && _eglIsCurrentThreadDummy())
      RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);

   t->CurrentAPIIndex = es_index;
   ret = eglWaitClient();
   t->CurrentAPIIndex = api_index;
   return ret;
}
예제 #14
0
파일: xeglgears.c 프로젝트: aosm/X11apps
static void
copy_gears(struct egl_manager *eman,
	   EGLint tile_w, EGLint tile_h, EGLint w, EGLint h)
{
   int x, y;

   eglWaitClient();

   for (x = 0; x < w; x += tile_w) {
      for (y = 0; y < h; y += tile_h) {

	 XCopyArea(eman->xdpy, eman->xpix, eman->xwin, eman->gc,
		   0, 0, tile_w, tile_h, x, y);
      }
   }
}
예제 #15
0
파일: qegl.cpp 프로젝트: Afreeca/qt
bool QEglContext::swapBuffers(EGLSurface surface)
{
    if(ctx == EGL_NO_CONTEXT)
        return false;

    bool ok = eglSwapBuffers(QEgl::display(), surface);
    if (!ok)
        qWarning() << "QEglContext::swapBuffers():" << QEgl::errorString();

#ifdef Q_OS_SYMBIAN
    if (apiChanged) {
        eglWaitClient();
        apiChanged = false;
    }
#endif
    return ok;
}
예제 #16
0
void QX11GLWindowSurface::flush(QWidget *widget, const QRegion &widgetRegion, const QPoint &offset)
{
    // We don't need to know the widget which initiated the flush. Instead we just use the offset
    // to translate the widgetRegion:
    Q_UNUSED(widget);

    if (m_backBuffer.isNull()) {
        qDebug("QX11GLWindowSurface::flush() - backBuffer is null, not flushing anything");
        return;
    }

    Q_ASSERT(window()->size() != m_backBuffer.size());

    // Wait for all GL rendering to the back buffer pixmap to complete before trying to
    // copy it to the window. We do this by making sure the pixmap's context is current
    // and then call eglWaitClient. The EGL 1.4 spec says eglWaitClient doesn't have to
    // block, just that "All rendering calls...are guaranteed to be executed before native
    // rendering calls". This makes it potentially less expensive than glFinish.
    QGLContext* ctx = static_cast<QX11GLPixmapData*>(m_backBuffer.data_ptr().data())->context();
    if (QGLContext::currentContext() != ctx && ctx && ctx->isValid())
        ctx->makeCurrent();
    eglWaitClient();

    if (m_windowGC == 0) {
        XGCValues attribs;
        attribs.graphics_exposures = False;
        m_windowGC = XCreateGC(X11->display, m_window->handle(), GCGraphicsExposures, &attribs);
    }

    int rectCount;
    XRectangle *rects = (XRectangle *)qt_getClipRects(widgetRegion, rectCount);
    if (rectCount <= 0)
        return;

    XSetClipRectangles(X11->display, m_windowGC, 0, 0, rects, rectCount, YXBanded);

    QRect dirtyRect = widgetRegion.boundingRect().translated(-offset);
    XCopyArea(X11->display, m_backBuffer.handle(), m_window->handle(), m_windowGC,
              dirtyRect.x(), dirtyRect.y(), dirtyRect.width(), dirtyRect.height(),
              dirtyRect.x(), dirtyRect.y());

    // Make sure the blit of the update from the back buffer to the window completes
    // before allowing rendering to start again to the back buffer. Otherwise the GPU
    // might start rendering to the back buffer again while the blit takes place.
    eglWaitNative(EGL_CORE_NATIVE_ENGINE);
}
예제 #17
0
QPixmap QX11GLWindowSurface::grabWidget(const QWidget *widget, const QRect& rect) const
{
    if (!widget || m_backBuffer.isNull())
        return QPixmap();

    QRect srcRect;

    // make sure the rect is inside the widget & clip to widget's rect
    if (!rect.isEmpty())
        srcRect = rect & widget->rect();
    else
        srcRect = widget->rect();

    if (srcRect.isEmpty())
        return QPixmap();

    // If it's a child widget we have to translate the coordinates
    if (widget != window())
        srcRect.translate(widget->mapTo(window(), QPoint(0, 0)));

    QPixmap::x11SetDefaultScreen(widget->x11Info().screen());

    QX11PixmapData *pmd = new QX11PixmapData(QPixmapData::PixmapType);
    pmd->resize(srcRect.width(), srcRect.height());
    QPixmap px(pmd);

    GC tmpGc = XCreateGC(X11->display, m_backBuffer.handle(), 0, 0);

    // Make sure all GL rendering is complete before copying the window
    QGLContext* ctx = static_cast<QX11GLPixmapData*>(m_backBuffer.pixmapData())->context();
    if (QGLContext::currentContext() != ctx && ctx && ctx->isValid())
        ctx->makeCurrent();
    eglWaitClient();

    // Copy srcRect from the backing store to the new pixmap
    XSetGraphicsExposures(X11->display, tmpGc, False);
    XCopyArea(X11->display, m_backBuffer.handle(), px.handle(), tmpGc,
              srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height(), 0, 0);
    XFreeGC(X11->display, tmpGc);

    // Wait until the copy has finised before allowing more rendering into the back buffer
    eglWaitNative(EGL_CORE_NATIVE_ENGINE);

    return px;
}
예제 #18
0
    void
    resize(int w, int h) {
        if (w == width && h == height) {
            return;
        }

        eglWaitClient();

        // We need to ensure that pending events are processed here, and XSync
        // with discard = True guarantees that, but it appears the limited
        // event processing we do so far is sufficient
        //XSync(display, True);

        Drawable::resize(w, h);

        resizeWindow(window, w, h);

        eglWaitNative(EGL_CORE_NATIVE_ENGINE);

        /*
         * Some implementations won't update the backbuffer unless we recreate
         * the EGL surface.
         */

        int eglWidth;
        int eglHeight;

        eglQuerySurface(eglDisplay, surface, EGL_WIDTH, &eglWidth);
        eglQuerySurface(eglDisplay, surface, EGL_HEIGHT, &eglHeight);

        if (eglWidth != width || eglHeight != height) {
            recreate();

            eglQuerySurface(eglDisplay, surface, EGL_WIDTH, &eglWidth);
            eglQuerySurface(eglDisplay, surface, EGL_HEIGHT, &eglHeight);
        }

        assert(eglWidth == width);
        assert(eglHeight == height);
    }
void CEglTest_EGL_Image_Multi_Thread_Sibling_VGImage_PassingEGLImage::doThreadFunctionL(TInt aIdx)
	{	
	INFO_PRINTF2(_L("CEglTest_EGL_Image_Multi_Thread_Sibling_VGImage_PassingEGLImage::doThreadFunctionL, Thread %d"),aIdx);
	CTestEglSession* eglSess = CTestEglSession::NewLC(Logger(), iDisplay, aIdx);
	eglSess->InitializeL();
	eglSess->OpenSgDriverL();	

	// check there is no eglImage at the start of either thread
	ASSERT_EGL_TRUE(iEGLImageShared == EGL_NO_IMAGE_KHR);
	
	// Wait for both thread to reach this point
	//	This is important for multicore platforms (i.e., naviengine) as the execution order is not known and it could
	//	happen that the first thread has already created the image before the second checks there is no eglImage 
	Rendezvous(aIdx);

	if(aIdx == 0)
		{
		// Create an EGLImage from the RSgImage (member variable as it is 'shared' in the thread function...) 
		INFO_PRINTF2(_L("Thread %d, Creating the shared EGLImage"),aIdx);
		iEGLImageShared = eglSess->eglCreateImageKhrL(iDisplay,EGL_NO_CONTEXT,EGL_NATIVE_PIXMAP_KHR,&iSgImageShared,KEglImageAttribsPreservedTrue);
		ASSERT_EGL_TRUE(iEGLImageShared != EGL_NO_IMAGE_KHR);
		iSgImageShared.Close();
		}
	
	Rendezvous(aIdx);
	
	if(aIdx == 1)
		{
		INFO_PRINTF2(_L("Thread %d, Creating a Surface and a Context bound to OpenVG"),aIdx);
		TUidPixelFormat pixelFormat = EglTestConversion::VgFormatToSgPixelFormat(KDefaultSurfaceFormat);
		TSgImageInfoOpenVgTarget imageInfo = TSgImageInfoOpenVgTarget(pixelFormat, KPixmapSize);
		// Create a pixmap surface matching the native image pixel format
		eglSess->CreatePixmapSurfaceAndMakeCurrentAndMatchL(imageInfo,CTestEglSession::EResourceCloseSgImageEarly);

		// Create a VGImage from the EGLImage
		INFO_PRINTF2(_L("Thread %d, Creating one VGImage from the shared EGLImage"),aIdx);
		VGImage vgImageLocal = eglSess->vgCreateImageTargetKHR((VGeglImageKHR)iEGLImageShared);	
		ASSERT_VG_TRUE(vgImageLocal != VG_INVALID_HANDLE);

		INFO_PRINTF2(_L("Thread %d, Drawing the VGImage to the current surface"),aIdx);
		// Copy the source VGImage to the surface
    	vgSetPixels(0, 0, vgImageLocal, 0, 0, KPixmapSize.iWidth, KPixmapSize.iHeight);
		ASSERT_TRUE(vgGetError()==VG_NO_ERROR);
		eglWaitClient();

		// we can now compare the VgImage to the one we expect from the main thread
		TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat);
		CFbsBitmap* refBitmap = eglSess->CreateReferenceBitmapL(bitmapMode, KPixmapSize, 5);
		CleanupStack::PushL(refBitmap);
		eglSess->CheckVgDrawingL(KDefaultSurfaceFormat, refBitmap);
		CleanupStack::PopAndDestroy(refBitmap);
		INFO_PRINTF2(_L("Thread %d, Drawing successful"),aIdx);

		vgDestroyImage(vgImageLocal);
		ASSERT_TRUE(vgGetError() == VG_NO_ERROR);
		}
	
	Rendezvous(aIdx);
	
	if(aIdx == 0)
		{
		ASSERT_EGL_TRUE(eglSess->DestroyEGLImage(iDisplay, iEGLImageShared));
		iEGLImageShared = EGL_NO_IMAGE_KHR;
		}
	
	// cleanup
	eglSess->CloseSgDriver();
	CleanupStack::PopAndDestroy(eglSess);
	}
void CEglTest_EGL_Image_Multi_Thread_Sibling_VGImage::doThreadFunctionL(TInt aIdx)
	{	
	INFO_PRINTF2(_L("CEglTest_EGL_Image_Multi_Thread_Sibling_VGImage::doThreadFunctionL, Thread %d"),aIdx);
	CTestEglSession* eglSess = CTestEglSession::NewLC(Logger(), iDisplay, aIdx);
	eglSess->InitializeL();
	eglSess->OpenSgDriverL();

	INFO_PRINTF2(_L("Thread %d, Creating a Surface and a Context bound to OpenVG"),aIdx);
	TUidPixelFormat pixelFormat = EglTestConversion::VgFormatToSgPixelFormat(KDefaultSurfaceFormat);
	TSgImageInfoOpenVgTarget imageInfo = TSgImageInfoOpenVgTarget(pixelFormat, KPixmapSize);
	// Create a pixmap surface matching the native image pixel format
	eglSess->CreatePixmapSurfaceAndMakeCurrentAndMatchL(imageInfo,CTestEglSession::EResourceCloseSgImageEarly);
	
	// Create a VGImage from the EGLImage
	INFO_PRINTF2(_L("Thread %d, Creating one VGImage from the shared EGLImage"),aIdx);
	VGImage vgImageLocal = eglSess->vgCreateImageTargetKHR((VGeglImageKHR)iEGLImageShared);	
	ASSERT_VG_TRUE(vgImageLocal != VG_INVALID_HANDLE);
	
	Rendezvous(aIdx);
		
	if(aIdx == 0)
		{
		INFO_PRINTF2(_L("Thread %d, Updating contents of the VGImage from the shared EGLImage"),aIdx);
		TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat);
		CFbsBitmap* bitmap = eglSess->CreateReferenceBitmapL(bitmapMode, KPixmapSize, 8);
    	// Add pixel data to the VGImage reference from the bitmap reference. 
        // Mind the fact that CFbsBitmap and VGImages use different coordinates origin!
		TSize bitmapSize = bitmap->SizeInPixels();
    	TUint8* address = reinterpret_cast<TUint8*>(bitmap->DataAddress());
    	TInt stride = bitmap->DataStride();
    	address += (bitmapSize.iHeight - 1) * stride;
        vgImageSubData(vgImageLocal, address, -stride, KDefaultSurfaceFormat, 0,0, bitmapSize.iWidth, bitmapSize.iHeight);
		delete bitmap;
        bitmap = NULL;
		ASSERT_TRUE(vgGetError()==VG_NO_ERROR);
		eglWaitClient();
		}

	Rendezvous(aIdx);
	
	if(aIdx == 1)
		{
		INFO_PRINTF2(_L("Thread %d, Drawing the VGImage to the current surface"),aIdx);
		// Copy the source VGImage to the surface
    	vgSetPixels(0, 0, vgImageLocal, 0, 0, KPixmapSize.iWidth, KPixmapSize.iHeight);
		ASSERT_TRUE(vgGetError()==VG_NO_ERROR);
		eglWaitClient();

		// we can now compare the VgImage to the one we expect after changing it in the other thread
		TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat);
		CFbsBitmap* refBitmap = eglSess->CreateReferenceBitmapL(bitmapMode, KPixmapSize, 8);
		CleanupStack::PushL(refBitmap);
		eglSess->CheckVgDrawingL(KDefaultSurfaceFormat, refBitmap);
		CleanupStack::PopAndDestroy(refBitmap);
		INFO_PRINTF2(_L("Thread %d, Drawing successful"),aIdx);
		}		
	
	// cleanup
	vgDestroyImage(vgImageLocal);
	ASSERT_TRUE(vgGetError() == VG_NO_ERROR);
	eglSess->CloseSgDriver();
	CleanupStack::PopAndDestroy(eglSess);
	}
예제 #21
0
//------------------------------------------------------------------------------
// eglWaitGL
//------------------------------------------------------------------------------
EGLAPI EGLBoolean EGLAPIENTRY
eglWaitGL(void)
{
	// TODO: this is not fully conforming to spec.
	return eglWaitClient();
}
/**
@SYMTestCaseID GRAPHICS-EGL-0130

@SYMTestPriority 1

@SYMPREQ 39

@SYMREQ See SGL.GT0386.401 document

@SYMTestCaseDesc
When a RSgImage is used as both the source and target of a draw operation, then the operation should not panic.
However the outcome is undefined.

@SYMTestActions
Create and fully construct an RSgImage object
Pass the RSgImage objects into eglCreateImageKHR() with
•	The target parameter set to EGL_NATIVE_PIXMAP_KHR
•	Use the current display and EGL_NO_CONTEXT
•	Use a NULL attr_list
Check that those calls to eglCreateImageKHR() do NOT return EGL_NO_IMAGE_KHR
Use vgCreateEGLImageTargetKHR() to construct a VGImage object from the just created EGLImage.
•	Check for errors
Create Pixmap Surface from the previous RSgImage and make it current in a way that is compatible as a target for the VGImage to be drawn to.
•	Set the iUsage bit to ESgUsageBitOpenVgSurface and ESgUsageBitOpenGlesSurface
Use OpenVG to draw a single patern to the left half of the VGImage created from the EGLImage.
Try to draw this VGImage to the right half of the pixmap surface currently linked to the context.
Call eglWaitClient() to finish the above drawing instructions synchronously.
Check that the pixmap contains expected pixel values.
Pass the VGImage into vgDestroyImage()
Pass the EGLImage into eglDestroyImageKHR()
Close the RSgImage
Destroy the pixmap
Check for memory and handle leaks

@SYMTestExpectedResults
This test is not supposed to panic.
The contents, though, are undefined since we are reading from and writing to the same memory
No memory or handle leaks.
*/
TVerdict CEglTest_EGL_Image_Self_Drawing::doTestStepL()
	{
	SetTestStepID(_L("GRAPHICS-EGL-0130"));
	INFO_PRINTF1(_L("CEglTest_EGL_Image_Self_Drawing::doTestStepL"));

	TBool ret = CheckForExtensionL(KEGL_RSgimage | KEGL_KHR_image_base | KEGL_KHR_image_pixmap | KVG_KHR_EGL_image);
	if(!ret)
		{
		// The extension is not supported
		RecordTestResultL();
		CloseTMSGraphicsStep();
		return TestStepResult();
		}

	// This test is performed for default pixel format
	PrintUsedPixelConfiguration();

	// Create display object
	GetDisplayL();
	CreateEglSessionL();
	iEglSess->InitializeL();
	iEglSess->OpenSgDriverL();

	// Create a reference bitmap which we use to init the SgImage (we use index=8)
	TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(iSourceFormat);
	CFbsBitmap* bitmap = iEglSess->CreateReferenceBitmapL(bitmapMode, KPixmapSize, 8);
	CleanupStack::PushL(bitmap);

	INFO_PRINTF1(_L("Creating one RSgImage"));
	TSgImageInfoTest imageInfo;
	imageInfo.iSizeInPixels = KPixmapSize;
	imageInfo.iPixelFormat = iSourceFormat;
#ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
	imageInfo.iUsage = ESgUsageBitOpenVgImage | ESgUsageBitOpenVgSurface;
#else
	imageInfo.iUsage = ESgUsageOpenVgImage | ESgUsageOpenVgTarget;
#endif //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
	RSgImage sgImage;
	CleanupClosePushL(sgImage);
	ASSERT_EQUALS(sgImage.Create(imageInfo, bitmap->DataAddress(),bitmap->DataStride()), KErrNone);

	INFO_PRINTF1(_L("Creating one EGLImage from it"));
	EGLImageKHR imageKHR = iEglSess->eglCreateImageKhrL(iDisplay, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, &sgImage, KEglImageAttribsPreservedTrue);
	ASSERT_EGL_TRUE(imageKHR != EGL_NO_IMAGE_KHR);

	INFO_PRINTF1(_L("Calling eglBindAPI(EGL_OPENVG_API)"));
	ASSERT_EGL_TRUE(eglBindAPI(EGL_OPENVG_API));

    EGLint numConfigsWithPre = 0;
    EGLConfig configWithPre;
    const EGLint KAttribImagePre[] = { EGL_MATCH_NATIVE_PIXMAP,  reinterpret_cast<EGLint>(&sgImage),
                                       EGL_RENDERABLE_TYPE,      EGL_OPENVG_BIT,
                                       EGL_SURFACE_TYPE,         EGL_PIXMAP_BIT | EGL_VG_ALPHA_FORMAT_PRE_BIT,
                                       EGL_NONE };
    ASSERT_EGL_TRUE(eglChooseConfig(iDisplay, KAttribImagePre, &configWithPre, 1, &numConfigsWithPre));

	// Create a pixmap surface from the native image
	INFO_PRINTF1(_L("Calling eglCreatePixmapSurface"));
	EGLSurface surface = eglCreatePixmapSurface(iDisplay, configWithPre, &sgImage, KPixmapAttribsVgAlphaFormatPre );
	ASSERT_EGL_TRUE(surface != EGL_NO_SURFACE);

	// Create a context for drawing to/reading from the pixmap surface and make it current
	INFO_PRINTF1(_L("Calling eglCreateContext"));
	EGLContext context = eglCreateContext(iDisplay, configWithPre, EGL_NO_CONTEXT, NULL);
	ASSERT_EGL_TRUE(context != EGL_NO_CONTEXT);

	INFO_PRINTF1(_L("Calling eglMakeCurrent"));
	ASSERT_EGL_TRUE(eglMakeCurrent(iDisplay, surface, surface, context));

	// Create a VGImage from the EGLImage
	INFO_PRINTF1(_L("Creating 1 VGImage from the EGLImage"));
	VGImage vgImage = iEglSess->vgCreateImageTargetKHR((VGeglImageKHR)imageKHR);
	ASSERT_VG_TRUE(vgImage != VG_INVALID_HANDLE);

    //Copy the source VGImage to the surface
	vgSetPixels(0, 0, vgImage, 0, 0, KPixmapSize.iWidth, KPixmapSize.iHeight);
	ASSERT_TRUE(vgGetError()==VG_NO_ERROR);
	eglWaitClient();

	//cleanup
	vgDestroyImage(vgImage);
	ASSERT_TRUE(vgGetError()==VG_NO_ERROR);
	ASSERT_EGL_TRUE(iEglSess->DestroyEGLImage(iDisplay, imageKHR));
	CleanupStack::PopAndDestroy(2, bitmap); // bitmap, sgImage
	//This test doesn't check the drawing because the content of the image are undefined
	//since we are using the same buffer both as target and as source
	//The main purpose of this test is to ensure we don't get a panic
	ASSERT_EGL_TRUE(eglDestroyContext(iDisplay, context));					//Closing eglContext
	context = EGL_NO_CONTEXT;
	ASSERT_EGL_TRUE(eglDestroySurface(iDisplay,surface));					//Destroying Target Surface handle
	CleanAll();

	RecordTestResultL();
	CloseTMSGraphicsStep();
	return TestStepResult();
	}
예제 #23
0
JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengles_EGL_eglWaitClient(JNIEnv *env, jclass clazz) {
    return eglWaitClient();
}
void CEglTest_EGL_Image_Multi_Thread_Exit_Thread::doThreadFunctionL(TInt aIdx)
	{	
	INFO_PRINTF2(_L("CEglTest_EGL_Image_Multi_Thread_Exit_Thread::doThreadFunctionL, Thread %d"),aIdx);
	CTestEglSession* eglSess = CTestEglSession::NewLC(Logger(), iDisplay, aIdx);
	eglSess->InitializeL();
	eglSess->OpenSgDriverL();

	// check there is no eglImage at the start of either thread
	ASSERT_EGL_TRUE(iEGLImageShared == EGL_NO_IMAGE_KHR);

	TRequestStatus statusThread0;
	if(aIdx == 1)
		{
		INFO_PRINTF2(_L("Thread %d, Asking to be notified when thread 0 exits"),aIdx);
		iThreadStatus[0].iThread.Logon(statusThread0);
		}
	
	Rendezvous(aIdx);
	
	//Thread 0 creates the EGLImage and exit
	if(aIdx == 0)	
		{
		// Create an EGLImage from the RSgImage (member variable as it is 'shared' in the thread function...) 
		INFO_PRINTF2(_L("Thread %d, Creating the shared EGLImage"),aIdx);
		iEGLImageShared = eglSess->eglCreateImageKhrL(iDisplay,EGL_NO_CONTEXT,EGL_NATIVE_PIXMAP_KHR,&iSgImageShared,KEglImageAttribsPreservedTrue);
		ASSERT_EGL_TRUE(iEGLImageShared != EGL_NO_IMAGE_KHR);
		iSgImageShared.Close();
		INFO_PRINTF2(_L("Thread %d -----  Exiting ---- EGLImage should be kept alive"),aIdx);
		}
	
	//Thread1 waits for Thread0 to exit and then uses the EGLImage and performs some drawing
	if(aIdx == 1)
		{
		INFO_PRINTF2(_L("Thread %d, Waiting for thread 0 to exit"),aIdx);
		User::WaitForRequest(statusThread0);

		INFO_PRINTF2(_L("Thread %d, Creating a Surface and a Context bound to OpenVG"),aIdx);
		TUidPixelFormat pixelFormat = EglTestConversion::VgFormatToSgPixelFormat(KDefaultSurfaceFormat);
		TSgImageInfoOpenVgTarget imageInfo = TSgImageInfoOpenVgTarget(pixelFormat, KPixmapSize);
		// Create a pixmap surface matching the native image pixel format
		eglSess->CreatePixmapSurfaceAndMakeCurrentAndMatchL(imageInfo,CTestEglSession::EResourceCloseSgImageEarly);

		// Create a VGImage from the EGLImage
		INFO_PRINTF2(_L("Thread %d, Creating one VGImage from the shared EGLImage"),aIdx);
		VGImage vgImageLocal = eglSess->vgCreateImageTargetKHR((VGeglImageKHR)iEGLImageShared);	
		ASSERT_VG_TRUE(vgImageLocal != VG_INVALID_HANDLE);

		INFO_PRINTF2(_L("Thread %d, Drawing the VGImage to the current surface"),aIdx);
		// Copy the source VGImage to the surface
    	vgSetPixels(0, 0, vgImageLocal, 0, 0, KPixmapSize.iWidth, KPixmapSize.iHeight);
		ASSERT_TRUE(vgGetError()==VG_NO_ERROR);
		eglWaitClient();

		// we can now compare the VgImage to the one we expect after changing it in the other thread
		TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat);
		CFbsBitmap* refBitmap = eglSess->CreateReferenceBitmapL(bitmapMode, KPixmapSize, 2);
		CleanupStack::PushL(refBitmap);
		eglSess->CheckVgDrawingL(KDefaultSurfaceFormat, refBitmap);
		CleanupStack::PopAndDestroy(refBitmap);
		INFO_PRINTF2(_L("Thread %d, Drawing successful"),aIdx);

		vgDestroyImage(vgImageLocal);
		ASSERT_TRUE(vgGetError() == VG_NO_ERROR);
		ASSERT_EGL_TRUE(eglSess->DestroyEGLImage(iDisplay, iEGLImageShared));
		iEGLImageShared = EGL_NO_IMAGE_KHR;
		}
	
	// cleanup
	eglSess->CloseSgDriver();
	CleanupStack::PopAndDestroy(eglSess);
	}
void CEglTest_EGL_Image_Multi_Thread_DrawAfterTerminate::doThreadFunctionL(TInt aIdx)
	{
	INFO_PRINTF2(_L("CEglTest_EGL_Image_Multi_Thread_DrawAfterTerminate::doThreadFunctionL, Thread %d"),aIdx);
	GetDisplayL();
	CTestEglSession* eglSess = CTestEglSession::NewLC(Logger(), iDisplay, aIdx);
	eglSess->InitializeL();
	eglSess->OpenSgDriverL();

	TRequestStatus statusThread1;
	VGImage vgImageLocal = VG_INVALID_HANDLE;
	EGLint surfaceWidth;
	EGLint surfaceHeigth;
	
	//Thread0 asks to be notified when Thread1 exits
	//Creates a RSgImage having the reference bitmap as content
	//Creates a EGLImage from the RSgImage
	//Creates a surface
	//Creates a VGImage from the EGLImage
	if(aIdx == 0)
		{
		// Thread0 asks to be notified when Thread1 exits
		iThreadStatus[1].iThread.Logon(statusThread1);

	    RSgImage rSgImageLocal;
		CleanupClosePushL(rSgImageLocal);

		// create a reference bitmap (we give index 9, as there's only 1 image in this test case)
		TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat);
		CFbsBitmap* bitmap = eglSess->CreateReferenceBitmapL(bitmapMode, KPixmapSize, 9);
		CleanupStack::PushL(bitmap);

		// Create an RSgImage
		INFO_PRINTF2(_L("Thread %d, Creating a RSgImage having the reference bitmap's content"),aIdx);
		TSgImageInfoOpenVgImage imageInfo = TSgImageInfoOpenVgImage(KDefaultSourceFormat, KPixmapSize);
		ASSERT_EQUALS(rSgImageLocal.Create(imageInfo,bitmap->DataAddress(),bitmap->DataStride()), KErrNone);
		CleanupStack::PopAndDestroy(bitmap);

		INFO_PRINTF2(_L("Thread %d, Creating an EGLImage from the shared RSgImage"),aIdx);
		EGLImageKHR eglImageLocal = eglSess->eglCreateImageKhrL(iDisplay, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, &rSgImageLocal, KEglImageAttribsPreservedTrue);
		ASSERT_EGL_TRUE(eglImageLocal != EGL_NO_IMAGE_KHR);
		CleanupStack::PopAndDestroy(&rSgImageLocal); 	//transferring ownership of the buffer to the EGLImage

		INFO_PRINTF2(_L("Thread %d, Creating a Surface and a Context bound to OpenVG"),aIdx);
		TUidPixelFormat pixelFormat = EglTestConversion::VgFormatToSgPixelFormat(KDefaultSurfaceFormat);
		TSgImageInfoOpenVgTarget imageInfo2 = TSgImageInfoOpenVgTarget(pixelFormat, KPixmapSize);
		// Create a pixmap surface matching the native image pixel format
		eglSess->CreatePixmapSurfaceAndMakeCurrentAndMatchL(imageInfo2,CTestEglSession::EResourceCloseSgImageEarly);

		//We now store the size of the surface because after eglTerminate is called on the display
		//it will not be possible to use explicitly all the resources linked to it
		//i.e. every call to an EGL API who takes a display as an argument will raise a EGL_BAD_DISPLAY error
		eglQuerySurface(iDisplay, eglSess->Surface(), EGL_WIDTH, &surfaceWidth);
		eglQuerySurface(iDisplay, eglSess->Surface(), EGL_HEIGHT, &surfaceHeigth);		
		
		INFO_PRINTF2(_L("Thread %d, Creating one VGImage from the EGLImage"),aIdx);
		vgImageLocal = eglSess->vgCreateImageTargetKHR((VGeglImageKHR)eglImageLocal);	
		ASSERT_VG_TRUE(vgImageLocal != VG_INVALID_HANDLE);
		ASSERT_EGL_TRUE(eglSess->DestroyEGLImage(iDisplay, eglImageLocal));
		}
	
	Rendezvous(aIdx);
	
	//Thread1 calls eglTerminate and exit
	if(aIdx == 1)
		{
		INFO_PRINTF2(_L(", Thread %d, Calling eglTerminate and exiting"),aIdx);
		TerminateDisplayL();
		}
	
	Rendezvous(aIdx);
	
	//Thread0 resumes when Thread1 exits
	//and it uses the resources that are linked to the just destroyed display
	if(aIdx == 0)
		{
		User::WaitForRequest(statusThread1);

		// It's still possible to use the current context, surface and VGImage even though the display has been terminated
		//Copy the source VGImage to the surface
    	vgSetPixels(0, 0, vgImageLocal, 0, 0, KPixmapSize.iWidth, KPixmapSize.iHeight);
		ASSERT_TRUE(vgGetError()==VG_NO_ERROR);
		eglWaitClient();

		// we can now compare the VgImage to the one we would expect for this particular thread
		TDisplayMode bitmapMode = EglTestConversion::PixelFormatToDisplayMode(KDefaultSourceFormat);
		CFbsBitmap* refBitmap = eglSess->CreateReferenceBitmapL(bitmapMode, KPixmapSize, 9);
		CleanupStack::PushL(refBitmap);
		eglSess->CheckVgDrawingL(KDefaultSurfaceFormat, refBitmap);
		CleanupStack::PopAndDestroy(refBitmap);
		INFO_PRINTF2(_L("Drawing successful, Thread %d"),aIdx);

		vgDestroyImage(vgImageLocal);
		ASSERT_TRUE(vgGetError() == VG_NO_ERROR);
		eglReleaseThread();
		}
	
	// cleanup
	eglSess->CloseSgDriver();
	CleanupStack::PopAndDestroy(eglSess);
	}
예제 #26
0
 ~EglDrawable() {
     eglDestroySurface(eglDisplay, surface);
     eglWaitClient();
     XDestroyWindow(display, window);
     eglWaitNative(EGL_CORE_NATIVE_ENGINE);
 }