static EGLSurface qt_egl_create_surface (QEglContext *context, QPaintDevice *device, const QEglProperties *properties = 0) { // Get the screen surface functions, which are used to create native ids. QGLScreen *glScreen = glScreenForDevice(device); if (!glScreen) return EGL_NO_SURFACE; QGLScreenSurfaceFunctions *funcs = glScreen->surfaceFunctions(); if (!funcs) return EGL_NO_SURFACE; // Create the native drawable for the paint device. int devType = device->devType(); EGLNativePixmapType pixmapDrawable = 0; EGLNativeWindowType windowDrawable = 0; bool ok; if (devType == QInternal::Pixmap) { ok = funcs->createNativePixmap(static_cast<QPixmap *>(device), &pixmapDrawable); } else if (devType == QInternal::Image) { ok = funcs->createNativeImage(static_cast<QImage *>(device), &pixmapDrawable); } else { ok = funcs->createNativeWindow(static_cast<QWidget *>(device), &windowDrawable); } if (!ok) { qWarning("QEglContext::createSurface(): Cannot create the native EGL drawable"); return EGL_NO_SURFACE; } // Create the EGL surface to draw into, based on the native drawable. const int *props; if (properties) props = properties->properties(); else props = 0; EGLSurface surf; if (devType == QInternal::Widget) { surf = eglCreateWindowSurface (context->display(), context->config(), windowDrawable, props); } else { surf = eglCreatePixmapSurface (context->display(), context->config(), pixmapDrawable, props); } if (surf == EGL_NO_SURFACE) qWarning("QEglContext::createSurface(): Unable to create EGL surface, error = 0x%x", eglGetError()); return surf; }
static void jni_eglCreatePixmapSurface(JNIEnv *_env, jobject _this, jobject out_sur, jobject display, jobject config, jobject native_pixmap, jintArray attrib_list) { if (display == NULL || config == NULL || native_pixmap == NULL || !validAttribList(_env, attrib_list)) { jniThrowException(_env, "java/lang/IllegalArgumentException", NULL); return; } EGLDisplay dpy = getDisplay(_env, display); EGLConfig cnf = getConfig(_env, config); jint* base = 0; SkBitmap const * nativeBitmap = (SkBitmap const *)_env->GetIntField(native_pixmap, gBitmap_NativeBitmapFieldID); SkPixelRef* ref = nativeBitmap ? nativeBitmap->pixelRef() : 0; if (ref == NULL) { jniThrowException(_env, "java/lang/IllegalArgumentException", "Bitmap has no PixelRef"); return; } SkSafeRef(ref); ref->lockPixels(); egl_native_pixmap_t pixmap; pixmap.version = sizeof(pixmap); pixmap.width = nativeBitmap->width(); pixmap.height = nativeBitmap->height(); pixmap.stride = nativeBitmap->rowBytes() / nativeBitmap->bytesPerPixel(); pixmap.format = convertPixelFormat(nativeBitmap->config()); pixmap.data = (uint8_t*)ref->pixels(); base = beginNativeAttribList(_env, attrib_list); EGLSurface sur = eglCreatePixmapSurface(dpy, cnf, &pixmap, base); endNativeAttributeList(_env, attrib_list, base); if (sur != EGL_NO_SURFACE) { _env->SetIntField(out_sur, gSurface_EGLSurfaceFieldID, (int)sur); _env->SetIntField(out_sur, gSurface_NativePixelRefFieldID, (int)ref); } else { ref->unlockPixels(); SkSafeUnref(ref); } }
int32_t ppb_graphics3d_resize_buffers(PP_Resource context, int32_t width, int32_t height) { if (width < 0 || height < 0) { trace_error("%s, width or height are negative\n", __func__); return PP_ERROR_BADARGUMENT; } struct pp_graphics3d_s *g3d = pp_resource_acquire(context, PP_RESOURCE_GRAPHICS3D); if (!g3d) { trace_error("%s, bad resource\n", __func__); return PP_ERROR_BADRESOURCE; } pthread_mutex_lock(&display.lock); g3d->width = width; g3d->height = height; EGLSurface old_surf = g3d->egl_surf; Pixmap old_pixmap = g3d->pixmap; // release possibly bound to other thread g3d->egl_surf and bind it to current eglMakeCurrent(display.egl, g3d->egl_surf, g3d->egl_surf, g3d->glc); g3d->pixmap = XCreatePixmap(display.x, DefaultRootWindow(display.x), g3d->width, g3d->height, DefaultDepth(display.x, 0)); g3d->egl_surf = eglCreatePixmapSurface(display.egl, g3d->egl_config, g3d->pixmap, NULL); // make new g3d->egl_surf current to current thread to release old_surf eglMakeCurrent(display.egl, g3d->egl_surf, g3d->egl_surf, g3d->glc); // clear surface glClearColor(0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); // destroy old egl surface and x pixmap eglDestroySurface(display.egl, old_surf); XFreePixmap(display.x, old_pixmap); pthread_mutex_unlock(&display.lock); pp_resource_release(context); return PP_OK; }
EGLSurface EGLDevice::createPixmap(int width, int height, NativePixmapType buf) { const EGLint attribs[] = { EGL_WIDTH, width, EGL_HEIGHT, height, EGL_NONE }; EGLSurface pbuf = eglCreatePixmapSurface(_eglDisplay, _eglConfig, buf, attribs); if (pbuf == EGL_NO_SURFACE) { log_error( "eglCreatePbufferFromClientBuffer() failed (error 0x%x)", eglGetError()); return EGL_NO_SURFACE; } _pbuffers.push_back(pbuf); return pbuf; }
QT_BEGIN_NAMESPACE EGLSurface QEglContext::createSurface(QPaintDevice *device, const QEglProperties *properties) { // Create the native drawable for the paint device. int devType = device->devType(); EGLNativePixmapType pixmapDrawable = 0; EGLNativeWindowType windowDrawable = 0; bool ok; if (devType == QInternal::Pixmap) { pixmapDrawable = 0; ok = (pixmapDrawable != 0); } else if (devType == QInternal::Widget) { windowDrawable = (EGLNativeWindowType)(static_cast<QWidget *>(device))->winId(); ok = (windowDrawable != 0); } else { ok = false; } if (!ok) { qWarning("QEglContext::createSurface(): Cannot create the native EGL drawable"); return EGL_NO_SURFACE; } // Create the EGL surface to draw into, based on the native drawable. const int *props; if (properties) props = properties->properties(); else props = 0; EGLSurface surf; if (devType == QInternal::Widget) surf = eglCreateWindowSurface(dpy, cfg, windowDrawable, props); else surf = eglCreatePixmapSurface(dpy, cfg, pixmapDrawable, props); if (surf == EGL_NO_SURFACE) { qWarning("QEglContext::createSurface(): Unable to create EGL surface, error = 0x%x", eglGetError()); } return surf; }
EGLSurface createBCMPixmapSurface(EGLDisplay display, EGLConfig config) { EGLint pixel_format = EGL_PIXEL_FORMAT_ARGB_8888_BRCM; EGLint rt; eglGetConfigAttrib(display, config, EGL_RENDERABLE_TYPE, &rt); if (rt & EGL_OPENGL_ES_BIT) { pixel_format |= EGL_PIXEL_FORMAT_RENDER_GLES_BRCM; pixel_format |= EGL_PIXEL_FORMAT_GLES_TEXTURE_BRCM; } if (rt & EGL_OPENGL_ES2_BIT) { pixel_format |= EGL_PIXEL_FORMAT_RENDER_GLES2_BRCM; pixel_format |= EGL_PIXEL_FORMAT_GLES2_TEXTURE_BRCM; } if (rt & EGL_OPENVG_BIT) { pixel_format |= EGL_PIXEL_FORMAT_RENDER_VG_BRCM; pixel_format |= EGL_PIXEL_FORMAT_VG_IMAGE_BRCM; } if (rt & EGL_OPENGL_BIT) { pixel_format |= EGL_PIXEL_FORMAT_RENDER_GL_BRCM; } EGLint pixmap[5]; pixmap[0] = 0; pixmap[1] = 0; pixmap[2] = 8; pixmap[3] = 8; pixmap[4] = pixel_format; eglCreateGlobalImageBRCM(8, 8, pixel_format, 0, 8*4, pixmap); EGLSurface surface = eglCreatePixmapSurface(display, config, pixmap, 0); if ( surface == EGL_NO_SURFACE ) { cerr << "Unable to create EGL surface (eglError: " << eglGetError() << ")" << endl; } return surface; }
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); }
void WinEGLView::CreateSurface() { EGLint surfaceAttributes[16]; uint i = 0; surfaceAttributes[i++] = EGL_NONE; if (mIsNeedPixmap) { mEGLSurface = eglCreatePixmapSurface(mEGLDisplay, mEGLConfig, mBitmapPixmap, surfaceAttributes); } else { mEGLSurface = eglCreateWindowSurface(mEGLDisplay, mEGLConfig, mEGLNativeWindow, surfaceAttributes); if (mEGLSurface == EGL_NO_SURFACE) { eglGetError(); // Clear error mEGLSurface = eglCreateWindowSurface(mEGLDisplay, mEGLConfig, nullptr, surfaceAttributes); } } MEDUSA_ASSERT_NOT_EQUAL(mEGLSurface, EGL_NO_SURFACE, ""); MEDUSA_ASSERT_FALSE(GetEGLError(), ""); }
EGLPixmapSurface::EGLPixmapSurface(GLPlatformSurface::SurfaceAttributes surfaceAttributes) : EGLOffScreenSurface(surfaceAttributes) { if (!m_configSelector) return; EGLConfig config = m_configSelector->pixmapContextConfig(); if (!config) { destroy(); return; } EGLint visualId = m_configSelector->nativeVisualId(config); if (visualId == -1) { destroy(); return; } NativePixmap pixmap; NativeWrapper::createPixmap(&pixmap, visualId, m_configSelector->attributes() & GLPlatformSurface::SupportAlpha); m_bufferHandle = pixmap; if (!m_bufferHandle) { destroy(); return; } m_drawable = eglCreatePixmapSurface(m_sharedDisplay, config, static_cast<EGLNativePixmapType>(m_bufferHandle), 0); if (m_drawable == EGL_NO_SURFACE) { LOG_ERROR("Failed to create EGL surface(%d).", eglGetError()); destroy(); } }
/** @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(); }
//egl init int common_eglinit(struct globalStruct* globals, int testID, int surfaceType, NATIVE_PIXMAP_STRUCT** pNativePixmapPtr) { EGLint iMajorVersion, iMinorVersion; EGLint ai32ContextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; globals->eglDisplay = eglGetDisplay((int)0); if (!eglInitialize(globals->eglDisplay, &iMajorVersion, &iMinorVersion)) return 1; eglBindAPI(EGL_OPENGL_ES_API); if (!TestEGLError("eglBindAPI")) return 1; EGLint pi32ConfigAttribs[5]; pi32ConfigAttribs[0] = EGL_SURFACE_TYPE; pi32ConfigAttribs[1] = EGL_WINDOW_BIT | EGL_PIXMAP_BIT; pi32ConfigAttribs[2] = EGL_RENDERABLE_TYPE; pi32ConfigAttribs[3] = EGL_OPENGL_ES2_BIT; pi32ConfigAttribs[4] = EGL_NONE; int iConfigs; if (!eglChooseConfig(globals->eglDisplay, pi32ConfigAttribs, &globals->eglConfig, 1, &iConfigs) || (iConfigs != 1)) { SGXPERF_ERR_printf("Error: eglChooseConfig() failed.\n"); return 1; } if(surfaceType == SGXPERF_SURFACE_TYPE_WINDOW) globals->eglSurface = eglCreateWindowSurface(globals->eglDisplay, globals->eglConfig, (EGLNativeWindowType) NULL, NULL); else if(surfaceType == SGXPERF_SURFACE_TYPE_PIXMAP_16) { common_create_native_pixmap(SGXPERF_RGB565, globals->inTextureWidth, globals->inTextureHeight, pNativePixmapPtr); globals->eglSurface = eglCreatePixmapSurface(globals->eglDisplay, globals->eglConfig, (EGLNativePixmapType)*pNativePixmapPtr, NULL); } else if(surfaceType == SGXPERF_SURFACE_TYPE_PIXMAP_32) { common_create_native_pixmap(SGXPERF_ARGB8888, globals->inTextureWidth, globals->inTextureHeight, pNativePixmapPtr); globals->eglSurface = eglCreatePixmapSurface(globals->eglDisplay, globals->eglConfig, (EGLNativePixmapType)*pNativePixmapPtr, NULL); } else return 999; if (!TestEGLError("eglCreateSurface")) return 1; if(testID == 14) //Create one pixmap surface for context switch latency check { common_create_native_pixmap(SGXPERF_RGB565, globals->inTextureWidth, globals->inTextureHeight, pNativePixmapPtr); globals->eglSurface2 = eglCreatePixmapSurface(globals->eglDisplay, globals->eglConfig, (EGLNativePixmapType)*pNativePixmapPtr, NULL); } if (!TestEGLError("eglCreateSurface")) return 1; globals->eglContext = eglCreateContext(globals->eglDisplay, globals->eglConfig, NULL, ai32ContextAttribs); if (!TestEGLError("eglCreateContext")) return 1; eglMakeCurrent(globals->eglDisplay, globals->eglSurface, globals->eglSurface, globals->eglContext); if (!TestEGLError("eglMakeCurrent")) return 1; eglSwapInterval(globals->eglDisplay, 1); if (!TestEGLError("eglSwapInterval")) return 1; eglQuerySurface(globals->eglDisplay, globals->eglSurface, EGL_WIDTH, &globals->windowWidth); eglQuerySurface(globals->eglDisplay, globals->eglSurface, EGL_HEIGHT, &globals->windowHeight); SGXPERF_printf("Window width=%d, Height=%d\n", globals->windowWidth, globals->windowHeight); return 0; }
static GF_Err EVID_InitSurface(GF_VideoOutput *dr) { TInt gl_buffer_size; TInt e; TDisplayMode disp_mode; TSize s; EPOCVideo *ctx = (EPOCVideo *)dr->opaque; GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[EPOC Video] Reseting video\n")); EVID_ResetSurface(dr, 0); GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[EPOC Video] Video reset OK\n")); ctx->screen = new CWsScreenDevice(*ctx->session); if (!ctx->screen) { GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOC Video] Cannot create screen device for session\n")); return GF_IO_ERR; } e = ctx->screen->Construct(); if (e != KErrNone) { GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOC Video] Cannot construct screen device for session - error %d\n", e)); return GF_IO_ERR; } e = ctx->screen->CreateContext(ctx->gc); if (e != KErrNone) { GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOC Video] Cannot create graphical context - error %d\n", e)); return GF_IO_ERR; } ctx->surface = new CFbsBitmap(); if (!ctx->surface) { GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOC Video] Cannot allocate backbuffer surface\n")); return GF_IO_ERR; } s = ctx->window->Size(); disp_mode = ctx->screen->DisplayMode(); e = ctx->surface->Create(s, disp_mode); if (e != KErrNone) { GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOC Video] Cannot create backbuffer surface - error %d\n", e)); return GF_IO_ERR; } gl_buffer_size = 0; switch (disp_mode) { case EGray256: ctx->pixel_format = GF_PIXEL_GREYSCALE; ctx->bpp = 1; break; case EColor64K: ctx->pixel_format = GF_PIXEL_RGB_565; ctx->bpp = 2; gl_buffer_size = 16; break; case EColor16M: ctx->pixel_format = GF_PIXEL_RGB_24; ctx->bpp = 3; gl_buffer_size = 24; break; /** 4096 colour display (12 bpp). */ case EColor4K: ctx->pixel_format = GF_PIXEL_RGB_444; ctx->bpp = 2; gl_buffer_size = 12; break; /** True colour display mode (32 bpp, but top byte is unused and unspecified) */ case EColor16MU: ctx->pixel_format = GF_PIXEL_RGB_32; ctx->bpp = 4; gl_buffer_size = 32; break; #if defined(__SERIES60_3X__) /** Display mode with alpha (24bpp colour plus 8bpp alpha) */ case EColor16MA: ctx->pixel_format = GF_PIXEL_ARGB; ctx->bpp = 4; gl_buffer_size = 32; break; #endif default: GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOC Video] Unsupported display type %d\n", disp_mode)); return GF_NOT_SUPPORTED; } ctx->width = s.iWidth; ctx->height = s.iHeight; #ifdef GPAC_USE_OGL_ES if (ctx->output_3d_type==1) { if (!gl_buffer_size) { GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOC Video] Display mode not supported by OpenGL\n")); return GF_IO_ERR; } ctx->egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (ctx->egl_display == NULL) { GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOC Video] Cannot open OpenGL display\n")); return GF_IO_ERR; } if (eglInitialize(ctx->egl_display, NULL, NULL) == EGL_FALSE) { GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOC Video] Cannot initialize OpenGL display\n")); return GF_IO_ERR; } EGLConfig *configList = NULL; EGLint numOfConfigs = 0; EGLint configSize = 0; if (eglGetConfigs(ctx->egl_display, configList, configSize, &numOfConfigs) == EGL_FALSE) { GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOC Video] Cannot retrieve OpenGL configurations\n")); return GF_IO_ERR; } configSize = numOfConfigs; configList = (EGLConfig*) gf_malloc(sizeof(EGLConfig)*configSize); // Define properties for the wanted EGLSurface EGLint atts[7]; const char *opt = gf_modules_get_option((GF_BaseInterface *)dr, "Video", "GLNbBitsDepth"); atts[0] = EGL_BUFFER_SIZE; atts[1] = gl_buffer_size; atts[2] = EGL_DEPTH_SIZE; atts[3] = opt ? atoi(opt) : 16; atts[4] = EGL_SURFACE_TYPE; atts[5] = EGL_PIXMAP_BIT; atts[6] = EGL_NONE; if (eglChooseConfig(ctx->egl_display, atts, configList, configSize, &numOfConfigs) == EGL_FALSE) { GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOC Video] Cannot choose OpenGL configuration\n")); return GF_IO_ERR; } EGLConfig gl_cfg = configList[0]; gf_free(configList); ctx->egl_surface = eglCreatePixmapSurface(ctx->egl_display, gl_cfg, ctx->surface, NULL); if (ctx->egl_surface == NULL) { GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOC Video] Cannot create OpenGL surface\n")); return GF_IO_ERR; } ctx->egl_context = eglCreateContext(ctx->egl_display, gl_cfg, EGL_NO_CONTEXT, NULL); if (ctx->egl_context == NULL) { GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOC Video] Cannot create OpenGL context\n")); return GF_IO_ERR; } if (eglMakeCurrent(ctx->egl_display, ctx->egl_surface, ctx->egl_surface, ctx->egl_context) == EGL_FALSE) { GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOC Video] Cannot bind OpenGL context to current thread\n")); return GF_IO_ERR; } GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[EPOC Video] Video OpenGL setup\n")); } #endif GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[EPOC Video] Video setup OK - %d x %d @ PixelFormat %s\n", ctx->width, ctx->height, gf_4cc_to_str(ctx->pixel_format) )); return GF_OK; }
GF_Err GAPI_SetupOGL_ES_Offscreen(GF_VideoOutput *dr, u32 width, u32 height) { int atts[15]; const char *opt; EGLint n, maj, min; GAPICTX(dr) GAPI_ReleaseOGL_ES(gctx, 1); if (!gctx->use_pbuffer) { SetWindowPos(gctx->gl_hwnd, NULL, 0, 0, width, height, SWP_NOZORDER | SWP_NOMOVE); createPixmap(gctx, 2); } gctx->egldpy = eglGetDisplay(/*gctx->dpy*/EGL_DEFAULT_DISPLAY); if (!eglInitialize(gctx->egldpy, &maj, &min)) { gctx->egldpy = NULL; return GF_IO_ERR; } atts[0] = EGL_RED_SIZE; atts[1] = 8; atts[2] = EGL_GREEN_SIZE; atts[3] = 8; atts[4] = EGL_BLUE_SIZE; atts[5] = 8; atts[6] = EGL_ALPHA_SIZE; atts[7] = (dr->hw_caps & GF_VIDEO_HW_OPENGL_OFFSCREEN_ALPHA) ? 8 : EGL_DONT_CARE; opt = gf_modules_get_option((GF_BaseInterface *)dr, "Video", "GLNbBitsDepth"); atts[8] = EGL_DEPTH_SIZE; atts[9] = opt ? atoi(opt) : 16; atts[10] = EGL_STENCIL_SIZE; atts[11] = EGL_DONT_CARE; atts[12] = EGL_SURFACE_TYPE; atts[13] = gctx->use_pbuffer ? EGL_PBUFFER_BIT : EGL_PIXMAP_BIT; atts[14] = EGL_NONE; eglGetConfigs(gctx->egldpy, NULL, 0, &n); if (!eglChooseConfig(gctx->egldpy, atts, &gctx->eglconfig, 1, &n)) { return GF_IO_ERR; } if (!gctx->use_pbuffer) { gctx->surface = eglCreatePixmapSurface(gctx->egldpy, gctx->eglconfig, gctx->gl_bitmap, 0); } else { atts[0] = EGL_WIDTH; atts[1] = width; atts[2] = EGL_HEIGHT; atts[3] = height; atts[4] = EGL_NONE; gctx->surface = eglCreatePbufferSurface(gctx->egldpy, gctx->eglconfig, atts); } if (!gctx->surface) { return GF_IO_ERR; } gctx->eglctx = eglCreateContext(gctx->egldpy, gctx->eglconfig, NULL, NULL); if (!gctx->eglctx) { eglDestroySurface(gctx->egldpy, gctx->surface); gctx->surface = 0L; return GF_IO_ERR; } if (!eglMakeCurrent(gctx->egldpy, gctx->surface, gctx->surface, gctx->eglctx)) { eglDestroyContext(gctx->egldpy, gctx->eglctx); gctx->eglctx = 0L; eglDestroySurface(gctx->egldpy, gctx->surface); gctx->surface = 0L; return GF_IO_ERR; } return GF_OK; }
GF_Err GAPI_SetupOGL_ES(GF_VideoOutput *dr) { EGLint n, maj, min; u32 i; GF_Event evt; GAPICTX(dr) static int atts[32]; const char *opt; i=0; atts[i++] = EGL_RED_SIZE; atts[i++] = (gctx->pixel_format==GF_PIXEL_RGB_24) ? 8 : 5; atts[i++] = EGL_GREEN_SIZE; atts[i++] = (gctx->pixel_format==GF_PIXEL_RGB_24) ? 8 : (gctx->pixel_format==GF_PIXEL_RGB_565) ? 6 : 5; atts[i++] = EGL_BLUE_SIZE; atts[i++] = (gctx->pixel_format==GF_PIXEL_RGB_24) ? 8 : 5; opt = gf_modules_get_option((GF_BaseInterface *)dr, "Video", "GLNbBitsDepth"); atts[i++] = EGL_DEPTH_SIZE; atts[i++] = opt ? atoi(opt) : 16; atts[i++] = EGL_SURFACE_TYPE; #ifdef GLES_NO_PIXMAP atts[i++] = EGL_WINDOW_BIT; #else atts[i++] = EGL_PIXMAP_BIT; // atts[i++] = gctx->fullscreen ? EGL_WINDOW_BIT : EGL_PIXMAP_BIT; #endif atts[i++] = EGL_ALPHA_SIZE; atts[i++] = EGL_DONT_CARE; atts[i++] = EGL_STENCIL_SIZE; atts[i++] = EGL_DONT_CARE; atts[i++] = EGL_NONE; /*whenever window is resized we must reinit OGL-ES*/ GAPI_ReleaseOGL_ES(gctx, 0); if (!gctx->fullscreen) { RECT rc; ::GetClientRect(gctx->hWnd, &rc); gctx->bb_width = rc.right-rc.left; gctx->bb_height = rc.bottom-rc.top; #ifndef GLES_NO_PIXMAP createPixmap(gctx, 1); #endif } gctx->egldpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (!gctx->egldpy) { GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[GAPI] Cannot get OpenGL display\n")); return GF_IO_ERR; } if (!eglInitialize(gctx->egldpy, &maj, &min)) { gctx->egldpy = NULL; GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[GAPI] Cannot initialize OpenGL layer\n")); return GF_IO_ERR; } if (!eglChooseConfig(gctx->egldpy, atts, &gctx->eglconfig, 1, &n) || (eglGetError() != EGL_SUCCESS)) { GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[GAPI] Cannot choose OpenGL config\n")); return GF_IO_ERR; } if (gctx->fullscreen #ifdef GLES_NO_PIXMAP || 1 #endif ) { gctx->surface = eglCreateWindowSurface(gctx->egldpy, gctx->eglconfig, gctx->hWnd, 0); } else { gctx->surface = eglCreatePixmapSurface(gctx->egldpy, gctx->eglconfig, gctx->bitmap, 0); } if (!gctx->surface) { GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[GAPI] Cannot create OpenGL surface - error %d\n", eglGetError())); return GF_IO_ERR; } gctx->eglctx = eglCreateContext(gctx->egldpy, gctx->eglconfig, NULL, NULL); if (!gctx->eglctx) { GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[GAPI] Cannot create OpenGL context\n")); eglDestroySurface(gctx->egldpy, gctx->surface); gctx->surface = 0L; return GF_IO_ERR; } if (!eglMakeCurrent(gctx->egldpy, gctx->surface, gctx->surface, gctx->eglctx)) { GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[GAPI] Cannot bind OpenGL context\n")); eglDestroyContext(gctx->egldpy, gctx->eglctx); gctx->eglctx = 0L; eglDestroySurface(gctx->egldpy, gctx->surface); gctx->surface = 0L; return GF_IO_ERR; } GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[GAPI] OpenGL initialize - %d x %d \n", gctx->bb_width, gctx->bb_height)); memset(&evt, 0, sizeof(GF_Event)); evt.type = GF_EVENT_VIDEO_SETUP; dr->on_event(dr->evt_cbk_hdl, &evt); return GF_OK; }
static DFBResult InitEGL( PVR2DData *pvr2d ) { EGLint iMajorVersion, iMinorVersion; EGLint ai32ContextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}; pvr2d->eglDisplay = eglGetDisplay((int)0); if (!eglInitialize(pvr2d->eglDisplay, &iMajorVersion, &iMinorVersion)) return DFB_INIT; pvr2d->eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC) eglGetProcAddress("eglCreateImageKHR"); if (pvr2d->eglCreateImageKHR == NULL) { D_ERROR( "DirectFB/PVR2D: eglCreateImageKHR not found!\n" ); return DFB_UNSUPPORTED; } pvr2d->glEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) eglGetProcAddress("glEGLImageTargetTexture2DOES"); if (pvr2d->glEGLImageTargetTexture2DOES == NULL) { D_ERROR( "DirectFB/PVR2D: glEGLImageTargetTexture2DOES not found!\n" ); return DFB_UNSUPPORTED; } eglBindAPI(EGL_OPENGL_ES_API); if (!TestEGLError("eglBindAPI")) return DFB_INIT; EGLint pi32ConfigAttribs[5]; pi32ConfigAttribs[0] = EGL_SURFACE_TYPE; pi32ConfigAttribs[1] = EGL_WINDOW_BIT | EGL_PIXMAP_BIT; pi32ConfigAttribs[2] = EGL_RENDERABLE_TYPE; pi32ConfigAttribs[3] = EGL_OPENGL_ES2_BIT; pi32ConfigAttribs[4] = EGL_NONE; int iConfigs; if (!eglChooseConfig(pvr2d->eglDisplay, pi32ConfigAttribs, &pvr2d->eglConfig, 1, &iConfigs) || (iConfigs != 1)) { D_ERROR("DirectFB/PVR2D: eglChooseConfig() failed.\n"); return DFB_INIT; } pvr2d->nativePixmap.ePixelFormat = 0; pvr2d->nativePixmap.eRotation = 0; pvr2d->nativePixmap.lWidth = pvr2d->lDisplayWidth; pvr2d->nativePixmap.lHeight = pvr2d->lDisplayHeight; pvr2d->nativePixmap.lStride = pvr2d->lStride; pvr2d->nativePixmap.lSizeInBytes = pvr2d->pFBMemInfo->ui32MemSize; pvr2d->nativePixmap.pvAddress = pvr2d->pFBMemInfo->ui32DevAddr; pvr2d->nativePixmap.lAddress = (long) pvr2d->pFBMemInfo->pBase; pvr2d->eglSurface = eglCreatePixmapSurface( pvr2d->eglDisplay, pvr2d->eglConfig, &pvr2d->nativePixmap, NULL ); if (!TestEGLError("eglCreatePixmapSurface")) return DFB_INIT; pvr2d->eglContext = eglCreateContext(pvr2d->eglDisplay, pvr2d->eglConfig, NULL, ai32ContextAttribs); if (!TestEGLError("eglCreateContext")) return DFB_INIT; eglMakeCurrent( pvr2d->eglDisplay, pvr2d->eglSurface, pvr2d->eglSurface, pvr2d->eglContext ); if (!TestEGLError("eglMakeCurrent")) return DFB_INIT; eglSwapInterval( pvr2d->eglDisplay, 1 ); if (!TestEGLError("eglSwapInterval")) return DFB_INIT; return DFB_OK; }
/***************************************************************************** * Function Name : InitAPI * Returns : true for success * Description : Initialise the 3D API *****************************************************************************/ bool PVRShellInit::ApiInitAPI() { int bDone; #if defined(BUILD_OGLES2) || defined(BUILD_OVG) EGLNativeDisplayType ndt; #else NativeDisplayType ndt; #endif gEglContext = 0; do { bDone = true; #if defined(BUILD_OGLES2) || defined(BUILD_OVG) ndt = (EGLNativeDisplayType)OsGetNativeDisplayType(); #else ndt = (NativeDisplayType)OsGetNativeDisplayType(); #endif gEglDisplay = eglGetDisplay(ndt); if(gEglDisplay == EGL_NO_DISPLAY) { #if defined(BUILD_OGLES2) || defined(BUILD_OVG) gEglDisplay = eglGetDisplay((EGLNativeDisplayType)EGL_DEFAULT_DISPLAY); #else gEglDisplay = eglGetDisplay((NativeDisplayType)EGL_DEFAULT_DISPLAY); #endif } if(!eglInitialize(gEglDisplay, &majorVersion, &minorVersion)) { m_pShell->PVRShellSet(prefExitMessage, "PVRShell: Unable to initialise EGL\n"); m_pShell->PVRShellOutputDebug("PVRShell: EGL Error (%s)\n", StringFrom_eglGetError()); return false; } m_pShell->PVRShellOutputDebug("PVRShell: EGL %d.%d initialized\n", majorVersion, minorVersion); // Check Extension avaliablility after EGL initialization if (majorVersion > 1 || (majorVersion == 1 && minorVersion >= 1)) { powerManagementSupported = true; } else { powerManagementSupported = PVRShellIsExtensionSupported(gEglDisplay,"EGL_IMG_power_management"); } PVRShellData ShellDataBackUp; memcpy((void*) &ShellDataBackUp, m_pShell->m_pShellData, sizeof(PVRShellData)); do { // bind OpenVG API if requested if(m_pShell->m_pShellData->bNeedOpenVG) { #ifndef BUILD_OVG m_pShell->PVRShellSet(prefExitMessage, "PVRShell: OpenVG not supported. Compile with BUILD_OVG defined."); return false; #else if(!eglBindAPI(EGL_OPENVG_API)) { m_pShell->PVRShellSet(prefExitMessage, "PVRShell: Failed to bind OpenVG API\n"); return false; } m_pShell->PVRShellOutputDebug("PVRShell: OpenVG bound\n"); // Find an EGL config gEglConfig = SelectEGLConfiguration(m_pShell->m_pShellData); #endif } else { #if defined(BUILD_OGL) if(!eglBindAPI(EGL_OPENGL_API)) { m_pShell->PVRShellSet(prefExitMessage, "PVRShell: Failed to bind OpenGL API\n"); return false; } #else #if defined EGL_VERSION_1_3 && defined GL_ES_VERSION_2_0 if(!eglBindAPI(EGL_OPENGL_ES_API)) { m_pShell->PVRShellSet(prefExitMessage, "PVRShell: Failed to bind OpenGL ES API\n"); return false; } #endif #endif // Find an EGL config gEglConfig = SelectEGLConfiguration(m_pShell->m_pShellData); } // Destroy the context if we already created one if (gEglContext) { eglDestroyContext(gEglDisplay, gEglContext); } // Attempt to create a context #if defined BUILD_OVG gEglContext = eglCreateContext(gEglDisplay, gEglConfig, NULL, NULL); #elif defined EGL_VERSION_1_3 && defined GL_ES_VERSION_2_0 EGLint ai32ContextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; gEglContext = eglCreateContext(gEglDisplay, gEglConfig, NULL, ai32ContextAttribs); #else gEglContext = eglCreateContext(gEglDisplay, gEglConfig, NULL, NULL); #endif if(gEglContext == EGL_NO_CONTEXT) { if(m_pShell->m_pShellData->bNeedPbuffer) { // Disable P-buffer and try again m_pShell->m_pShellData->bNeedPbuffer = false; } else if(m_pShell->m_pShellData->bNeedStencilBuffer) { // Disable Stencil Buffer and try again m_pShell->m_pShellData->bNeedStencilBuffer = false; } else if(m_pShell->m_pShellData->nFSAAMode > 0) { // Still failing, reduce the mode of AA and try again --m_pShell->m_pShellData->nFSAAMode; } else if(!m_pShell->m_pShellData->bSoftwareRender) { // Still failing, reset everything and try using a software renderer memcpy(m_pShell->m_pShellData, (void*) &ShellDataBackUp, sizeof(PVRShellData)); m_pShell->m_pShellData->bSoftwareRender = true; } else { m_pShell->PVRShellSet(prefExitMessage, "PVRShell: Unable to create a context\n"); return false; } } } while(gEglContext == EGL_NO_CONTEXT); if(m_pShell->m_pShellData->bSoftwareRender) { m_pShell->PVRShellOutputDebug("PVRShell: Warning! Using the SOFTWARE renderer\n"); } EGLint attrib_list[16]; int i = 0; #if defined(EGL_VERSION_1_2) if(m_pShell->m_pShellData->bNeedAlphaFormatPre) // The default is EGL_ALPHA_FORMAT_NONPRE { attrib_list[i++] = EGL_ALPHA_FORMAT; attrib_list[i++] = EGL_ALPHA_FORMAT_PRE; } #endif // Terminate the attribute list with EGL_NONE attrib_list[i] = EGL_NONE; if(m_pShell->m_pShellData->bNeedPixmap) { #if defined(BUILD_OGLES2) || defined(BUILD_OVG) EGLNativePixmapType npt = (EGLNativePixmapType)OsGetNativePixmapType(); #else NativePixmapType npt = (NativePixmapType)OsGetNativePixmapType(); #endif m_pShell->PVRShellOutputDebug("InitAPI() Using pixmaps, about to create egl surface\n"); gEglWindow = eglCreatePixmapSurface(gEglDisplay, gEglConfig, npt, attrib_list); } else { #if defined(BUILD_OGLES2) || defined(BUILD_OVG) EGLNativeWindowType nwt = (EGLNativeWindowType)OsGetNativeWindowType(); #else NativeWindowType nwt = (NativeWindowType)OsGetNativeWindowType(); #endif gEglWindow = eglCreateWindowSurface(gEglDisplay, gEglConfig, nwt, attrib_list); // If we have failed to create a surface then try using Null if(gEglWindow == EGL_NO_SURFACE) { gEglWindow = eglCreateWindowSurface(gEglDisplay, gEglConfig, NULL, attrib_list); } } if (gEglWindow == EGL_NO_SURFACE) { m_pShell->PVRShellSet(prefExitMessage, "PVRShell: Unable to create surface\n"); return false; } if (!eglMakeCurrent(gEglDisplay, gEglWindow, gEglWindow, gEglContext)) { #ifdef EGL_VERSION_1_3 if((eglGetError() == EGL_CONTEXT_LOST)) #else if((eglGetError() == EGL_CONTEXT_LOST_IMG) && powerManagementSupported) #endif { bDone = false; } else { m_pShell->PVRShellSet(prefExitMessage, "PVRShell: Unable to make context current\n"); return false; } } } while(!bDone); /* Get correct screen width and height and save them into m_pShell->m_pShellData->nShellDimX and m_pShell->m_pShellData->nShellDimY */ eglQuerySurface(gEglDisplay, gEglWindow, EGL_WIDTH, (EGLint*)&m_pShell->m_pShellData->nShellDimX ); eglQuerySurface(gEglDisplay, gEglWindow, EGL_HEIGHT, (EGLint*)&m_pShell->m_pShellData->nShellDimY ); /* Done - activate requested features */ ApiActivatePreferences(); return true; }
EGLSurface QEgl::createSurface(QPaintDevice *device, EGLConfig cfg, const QEglProperties *properties) { // Create the native drawable for the paint device. int devType = device->devType(); EGLNativePixmapType pixmapDrawable = 0; EGLNativeWindowType windowDrawable = 0; bool ok; if (devType == QInternal::Pixmap) { pixmapDrawable = nativePixmap(static_cast<QPixmap *>(device)); ok = (pixmapDrawable != 0); } else if (devType == QInternal::Widget) { windowDrawable = nativeWindow(static_cast<QWidget *>(device)); ok = (windowDrawable != 0); } else { ok = false; } if (!ok) { qWarning("QEglContext::createSurface(): Cannot create the native EGL drawable"); return EGL_NO_SURFACE; } // Create the EGL surface to draw into, based on the native drawable. const int *props; if (properties) props = properties->properties(); else props = 0; EGLSurface surf = EGL_NO_SURFACE; #ifdef Q_OS_SYMBIAN // On Symbian there might be situations (especially on 32MB GPU devices) // where Qt is trying to create EGL surface while some other application // is still holding all available GPU memory but is about to release it // soon. For an example when exiting native video recorder and going back to // Qt application behind it. Video stack tear down takes some time and Qt // app might be too quick in reserving its EGL surface and thus running out // of GPU memory right away. So if EGL surface creation fails due to bad // alloc, let's try recreating it four times within ~1 second if needed. // This strategy gives some time for video recorder to tear down its stack // and a chance to Qt for creating a valid surface. // If the surface is still failing however, we don't keep the app blocked. static int tries = 4; if (tries <= 0) tries = 1; while (tries-- > 0) { if (devType == QInternal::Widget) surf = eglCreateWindowSurface(QEgl::display(), cfg, windowDrawable, props); else surf = eglCreatePixmapSurface(QEgl::display(), cfg, pixmapDrawable, props); if (surf == EGL_NO_SURFACE) { EGLint error = eglGetError(); if (error == EGL_BAD_ALLOC) { if (tries > 0) { User::After(1000 * 250); // 250ms continue; } } qWarning("QEglContext::createSurface(): Unable to create EGL surface, error = 0x%x", error); S60->eglSurfaceCreationError = true; } else { tries = 4; break; } } #else if (devType == QInternal::Widget) surf = eglCreateWindowSurface(QEgl::display(), cfg, windowDrawable, props); else surf = eglCreatePixmapSurface(QEgl::display(), cfg, pixmapDrawable, props); if (surf == EGL_NO_SURFACE) { qWarning("QEglContext::createSurface(): Unable to create EGL surface, error = 0x%x", eglGetError()); } #endif return surf; }
// NOTE: The X11 version of createSurface will re-create the native drawable if it's visual doesn't // match the one for the passed in EGLConfig EGLSurface QEgl::createSurface(QPaintDevice *device, EGLConfig config, const QEglProperties *unusedProperties) { Q_UNUSED(unusedProperties); int devType = device->devType(); if (devType == QInternal::Pbuffer) { // TODO return EGL_NO_SURFACE; } QX11PixmapData *x11PixmapData = 0; if (devType == QInternal::Pixmap) { QPixmapData *pmd = static_cast<QPixmap*>(device)->data_ptr().data(); if (pmd->classId() == QPixmapData::X11Class) x11PixmapData = static_cast<QX11PixmapData*>(pmd); else { // TODO: Replace the pixmap's data with a new QX11PixmapData qWarning("WARNING: Creating an EGL surface on a QPixmap is only supported for QX11PixmapData"); return EGL_NO_SURFACE; } } else if ((devType != QInternal::Widget) && (devType != QInternal::Pbuffer)) { qWarning("WARNING: Creating an EGLSurface for device type %d isn't supported", devType); return EGL_NO_SURFACE; } VisualID visualId = QEgl::getCompatibleVisualId(config); EGLint alphaSize; eglGetConfigAttrib(QEgl::display(), config, EGL_ALPHA_SIZE, &alphaSize); if (devType == QInternal::Widget) { QWidget *widget = static_cast<QWidget*>(device); VisualID currentVisualId = 0; if (widget->testAttribute(Qt::WA_WState_Created)) currentVisualId = XVisualIDFromVisual((Visual*)widget->x11Info().visual()); if (currentVisualId != visualId) { // The window is either not created or has the wrong visual. Either way, we need // to create a window with the correct visual and call create() on the widget: bool visible = widget->isVisible(); if (visible) widget->hide(); XVisualInfo visualInfo; visualInfo.visualid = visualId; { XVisualInfo *visualInfoPtr; int matchingCount = 0; visualInfoPtr = XGetVisualInfo(widget->x11Info().display(), VisualIDMask, &visualInfo, &matchingCount); Q_ASSERT(visualInfoPtr); // visualId really should be valid! visualInfo = *visualInfoPtr; XFree(visualInfoPtr); } Window parentWindow = RootWindow(widget->x11Info().display(), widget->x11Info().screen()); if (widget->parentWidget()) parentWindow = widget->parentWidget()->winId(); XSetWindowAttributes windowAttribs; QColormap colmap = QColormap::instance(widget->x11Info().screen()); windowAttribs.background_pixel = colmap.pixel(widget->palette().color(widget->backgroundRole())); windowAttribs.border_pixel = colmap.pixel(Qt::black); unsigned int valueMask = CWBackPixel|CWBorderPixel; if (alphaSize > 0) { windowAttribs.colormap = XCreateColormap(widget->x11Info().display(), parentWindow, visualInfo.visual, AllocNone); valueMask |= CWColormap; } Window window = XCreateWindow(widget->x11Info().display(), parentWindow, widget->x(), widget->y(), widget->width(), widget->height(), 0, visualInfo.depth, InputOutput, visualInfo.visual, valueMask, &windowAttribs); // This is a nasty hack to get round the fact that we can't be a friend of QWidget: qt_set_winid_on_widget(widget, window); if (visible) widget->show(); } // At this point, the widget's window should be created and have the correct visual. Now we // just need to create the EGL surface for it: EGLSurface surf = eglCreateWindowSurface(QEgl::display(), config, (EGLNativeWindowType)widget->winId(), 0); if (surf == EGL_NO_SURFACE) qWarning("QEglContext::createSurface(): Unable to create EGL surface, error = 0x%x", eglGetError()); return surf; } if (x11PixmapData) { // X11 Pixmaps are only created with a depth, so that's all we need to check EGLint configDepth; eglGetConfigAttrib(QEgl::display(), config, EGL_BUFFER_SIZE , &configDepth); if (x11PixmapData->depth() != configDepth) { // The bit depths are wrong which means the EGLConfig isn't compatable with // this pixmap. So we need to replace the pixmap's existing data with a new // one which is created with the correct depth: #ifndef QT_NO_XRENDER if (configDepth == 32) { qWarning("Warning: EGLConfig's depth (32) != pixmap's depth (%d), converting to ARGB32", x11PixmapData->depth()); x11PixmapData->convertToARGB32(true); } else #endif { qWarning("Warning: EGLConfig's depth (%d) != pixmap's depth (%d)", configDepth, x11PixmapData->depth()); } } QEglProperties surfaceAttribs; // If the pixmap can't be bound to a texture, it's pretty useless surfaceAttribs.setValue(EGL_TEXTURE_TARGET, EGL_TEXTURE_2D); if (alphaSize > 0) surfaceAttribs.setValue(EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA); else surfaceAttribs.setValue(EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGB); EGLSurface surf = eglCreatePixmapSurface(QEgl::display(), config, (EGLNativePixmapType) x11PixmapData->handle(), surfaceAttribs.properties()); x11PixmapData->gl_surface = (void*)surf; QImagePixmapCleanupHooks::enableCleanupHooks(x11PixmapData); return surf; } return EGL_NO_SURFACE; }
EGLSurface eglCreateWindowSurface(EGLDisplay egldisplay, EGLConfig config, NativeWindowType native_window, EGLint const * attrib_list) { if (x11_enabled == 0) { return real_eglCreateWindowSurface(egldisplay,config,native_window,attrib_list); } window = (Window*) native_window; puts("Getting window information..."); XWindowAttributes window_attributes; XGetWindowAttributes(display,window,&window_attributes); printf("Window Location: %i,%i \n Window Dimensions %i x %i \n Bit depth : %i \n",window_attributes.x,window_attributes.y,window_attributes.width,window_attributes.height,window_attributes.depth); width=window_attributes.width ; height=window_attributes.height; depth=window_attributes.depth; EGLint attr[] = { // some attributes to set up our egl-interface EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_SURFACE_TYPE, EGL_PIXMAP_BIT | EGL_OPENGL_ES2_BIT, EGL_NONE }; EGLConfig ecfg; EGLint num_config; if (!eglChooseConfig(edisplay, attr, &ecfg, 1, &num_config)) { fprintf(stderr, "Failed to choose config (eglError: %s)\n"); return EGL_NO_SURFACE; } EGLint pixel_format = EGL_PIXEL_FORMAT_ARGB_8888_BRCM; EGLint rt; eglGetConfigAttrib(edisplay, ecfg, EGL_RENDERABLE_TYPE, &rt); if (rt & EGL_OPENGL_ES_BIT) { pixel_format |= EGL_PIXEL_FORMAT_RENDER_GLES_BRCM; pixel_format |= EGL_PIXEL_FORMAT_GLES_TEXTURE_BRCM; } if (rt & EGL_OPENGL_ES2_BIT) { pixel_format |= EGL_PIXEL_FORMAT_RENDER_GLES2_BRCM; pixel_format |= EGL_PIXEL_FORMAT_GLES2_TEXTURE_BRCM; } if (rt & EGL_OPENVG_BIT) { pixel_format |= EGL_PIXEL_FORMAT_RENDER_VG_BRCM; pixel_format |= EGL_PIXEL_FORMAT_VG_IMAGE_BRCM; } if (rt & EGL_OPENGL_BIT) { pixel_format |= EGL_PIXEL_FORMAT_RENDER_GL_BRCM; } EGLint pixmap[5]; pixmap[0] = 0; pixmap[1] = 0; pixmap[2] = width; pixmap[3] = height; pixmap[4] = pixel_format; eglCreateGlobalImageBRCM(width, height, pixmap[4], 0, width*4, pixmap); egl_surface = eglCreatePixmapSurface(edisplay, ecfg, pixmap, 0); puts("EGL Surface Created"); EGLint ctxattr[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; EGLContext context = eglCreateContext ( edisplay, ecfg, EGL_NO_CONTEXT, ctxattr ); real_eglMakeCurrent(edisplay, egl_surface, egl_surface, context); return egl_surface; }
PP_Resource ppb_graphics3d_create(PP_Instance instance, PP_Resource share_context, const int32_t attrib_list[]) { struct pp_instance_s *pp_i = tables_get_pp_instance(instance); if (!pp_i) { trace_error("%s, bad instance\n", __func__); return 0; } PP_Resource context = pp_resource_allocate(PP_RESOURCE_GRAPHICS3D, pp_i); struct pp_graphics3d_s *g3d = pp_resource_acquire(context, PP_RESOURCE_GRAPHICS3D); if (!g3d) { trace_error("%s, can't create context\n", __func__); return 0; } int attrib_len = 0; while (attrib_list[attrib_len] != PP_GRAPHICS3DATTRIB_NONE) { attrib_len += 2; } attrib_len ++; EGLint *egl_attribute_list = calloc(attrib_len + 3 * 2, sizeof(EGLint)); int done = 0, k1 = 0, k2 = 0; egl_attribute_list[k2++] = EGL_SURFACE_TYPE; egl_attribute_list[k2++] = EGL_PIXMAP_BIT | EGL_WINDOW_BIT; egl_attribute_list[k2++] = EGL_RENDERABLE_TYPE; egl_attribute_list[k2++] = EGL_OPENGL_ES2_BIT; while (!done) { switch (attrib_list[k1]) { case PP_GRAPHICS3DATTRIB_HEIGHT: g3d->height = attrib_list[k1 + 1]; k1 += 2; break; case PP_GRAPHICS3DATTRIB_WIDTH: g3d->width = attrib_list[k1 + 1]; k1 += 2; break; case PP_GRAPHICS3DATTRIB_GPU_PREFERENCE: case PP_GRAPHICS3DATTRIB_SWAP_BEHAVIOR: // TODO: save these values k1 += 2; break; case PP_GRAPHICS3DATTRIB_NONE: egl_attribute_list[k2++] = EGL_NONE; done = 1; break; case PP_GRAPHICS3DATTRIB_ALPHA_SIZE: egl_attribute_list[k2++] = EGL_ALPHA_SIZE; egl_attribute_list[k2++] = attrib_list[k1 + 1]; k1 += 2; break; case PP_GRAPHICS3DATTRIB_BLUE_SIZE: egl_attribute_list[k2++] = EGL_BLUE_SIZE; egl_attribute_list[k2++] = attrib_list[k1 + 1]; k1 += 2; break; case PP_GRAPHICS3DATTRIB_GREEN_SIZE: egl_attribute_list[k2++] = EGL_GREEN_SIZE; egl_attribute_list[k2++] = attrib_list[k1 + 1]; k1 += 2; break; case PP_GRAPHICS3DATTRIB_RED_SIZE: egl_attribute_list[k2++] = EGL_RED_SIZE; egl_attribute_list[k2++] = attrib_list[k1 + 1]; k1 += 2; break; case PP_GRAPHICS3DATTRIB_DEPTH_SIZE: egl_attribute_list[k2++] = EGL_DEPTH_SIZE; egl_attribute_list[k2++] = attrib_list[k1 + 1]; k1 += 2; break; case PP_GRAPHICS3DATTRIB_STENCIL_SIZE: egl_attribute_list[k2++] = EGL_STENCIL_SIZE; egl_attribute_list[k2++] = attrib_list[k1 + 1]; k1 += 2; break; case PP_GRAPHICS3DATTRIB_SAMPLES: egl_attribute_list[k2++] = EGL_SAMPLES; egl_attribute_list[k2++] = attrib_list[k1 + 1]; k1 += 2; break; case PP_GRAPHICS3DATTRIB_SAMPLE_BUFFERS: egl_attribute_list[k2++] = EGL_SAMPLE_BUFFERS; egl_attribute_list[k2++] = attrib_list[k1 + 1]; k1 += 2; break; default: // skip unknown attribute trace_error("%s, unknown attribute 0x%x\n", __func__, attrib_list[k1]); k1 += 1; break; } } pthread_mutex_lock(&display.lock); int nconfigs = 0; EGLBoolean ret = eglChooseConfig(display.egl, egl_attribute_list, &g3d->egl_config, 1, &nconfigs); free(egl_attribute_list); if (!ret) { trace_error("%s, eglChooseConfig returned FALSE\n", __func__); goto err; } if (nconfigs != 1) { trace_error("%s, eglChooseConfig returned %d configs, expected 1\n", __func__, nconfigs); goto err; } // TODO: support shared_context EGLint ctxattr[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; g3d->glc = eglCreateContext(display.egl, g3d->egl_config, EGL_NO_CONTEXT, ctxattr); if (g3d->glc == EGL_NO_CONTEXT) { trace_error("%s, eglCreateContext returned EGL_NO_CONTEXT\n", __func__); goto err; } g3d->pixmap = XCreatePixmap(display.x, DefaultRootWindow(display.x), g3d->width, g3d->height, DefaultDepth(display.x, 0)); g3d->egl_surf = eglCreatePixmapSurface(display.egl, g3d->egl_config, g3d->pixmap, NULL); if (g3d->egl_surf == EGL_NO_SURFACE) { trace_error("%s, failed to create EGL pixmap surface\n", __func__); goto err; } ret = eglMakeCurrent(display.egl, g3d->egl_surf, g3d->egl_surf, g3d->glc); if (!ret) { trace_error("%s, eglMakeCurrent failed\n", __func__); goto err; } // clear surface glClearColor(0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); if (pp_i->is_transparent) { // create texture for plugin content glGenTextures(1, &g3d->tex_front); glBindTexture(GL_TEXTURE_2D, g3d->tex_front); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); if (create_presentation_egl_context(g3d) != 0) { trace_error("%s, can't create EGL context for transparency processing\n", __func__); goto err; } } eglMakeCurrent(display.egl, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); g3d->sub_maps = g_hash_table_new(g_direct_hash, g_direct_equal); pthread_mutex_unlock(&display.lock); pp_resource_release(context); return context; err: pthread_mutex_unlock(&display.lock); pp_resource_release(context); pp_resource_expunge(context); return 0; }
/***************************************************************************** * Function Name : ApiInitAPI * Returns : true for success * Description : Initialise the 3D API *****************************************************************************/ bool PVRShellInit::ApiInitAPI() { int bDone; m_NDT = (EGLNativeDisplayType)OsGetNativeDisplayType(); m_NPT = (EGLNativePixmapType) OsGetNativePixmapType(); m_NWT = (EGLNativeWindowType) OsGetNativeWindowType(); m_EGLContext = 0; do { bDone = true; m_EGLDisplay = eglGetDisplay(m_NDT); if(m_EGLDisplay == EGL_NO_DISPLAY) { #if defined(BUILD_OGLES2) || defined(BUILD_OVG) || defined(BUILD_OGLES3) m_EGLDisplay = eglGetDisplay((EGLNativeDisplayType)EGL_DEFAULT_DISPLAY); #else m_EGLDisplay = eglGetDisplay((NativeDisplayType)EGL_DEFAULT_DISPLAY); #endif } if(!eglInitialize(m_EGLDisplay, &m_MajorVersion, &m_MinorVersion)) { m_pShell->PVRShellSet(prefExitMessage, "PVRShell: Unable to initialise EGL\n"); m_pShell->PVRShellOutputDebug("PVRShell: EGL Error (%s)\n", StringFrom_eglGetError()); return false; } m_pShell->PVRShellOutputDebug("PVRShell: EGL %d.%d initialized\n", m_MajorVersion, m_MinorVersion); // Check Extension avaliablility after EGL initialization if (m_MajorVersion > 1 || (m_MajorVersion == 1 && m_MinorVersion >= 1)) { m_bPowerManagementSupported = true; } else { m_bPowerManagementSupported = PVRShellIsExtensionSupported(m_EGLDisplay,"EGL_IMG_power_management"); } do { // bind OpenVG API if requested if(m_pShell->m_pShellData->bNeedOpenVG) { #ifndef BUILD_OVG m_pShell->PVRShellSet(prefExitMessage, "PVRShell: OpenVG not supported. Compile with BUILD_OVG defined."); return false; #else if(!eglBindAPI(EGL_OPENVG_API)) { m_pShell->PVRShellSet(prefExitMessage, "PVRShell: Failed to bind OpenVG API\n"); return false; } m_pShell->PVRShellOutputDebug("PVRShell: OpenVG bound\n"); #endif } else { #if defined(BUILD_OGL) if(!eglBindAPI(EGL_OPENGL_API)) { m_pShell->PVRShellSet(prefExitMessage, "PVRShell: Failed to bind OpenGL API\n"); return false; } #else #if defined EGL_VERSION_1_3 && defined GL_ES_VERSION_2_0 if(!eglBindAPI(EGL_OPENGL_ES_API)) { m_pShell->PVRShellSet(prefExitMessage, "PVRShell: Failed to bind OpenGL ES API\n"); return false; } #endif #endif } // Find an EGL config m_EGLConfig = SelectEGLConfiguration(m_pShell->m_pShellData); eglGetConfigAttrib(m_EGLDisplay, m_EGLConfig, EGL_CONFIG_ID, &m_iConfig); // Destroy the context if we already created one if (m_EGLContext) { eglDestroyContext(m_EGLDisplay, m_EGLContext); } // Attempt to create a context EGLint ai32ContextAttribs[32]; int i = 0; #if defined(EGL_VERSION_1_3) && defined(GL_ES_VERSION_2_0) ai32ContextAttribs[i++] = EGL_CONTEXT_CLIENT_VERSION; ai32ContextAttribs[i++] = 2; #endif #if defined(BUILD_OGLES2) || defined(BUILD_OGLES) || defined(BUILD_OGLES3) if(PVRShellIsExtensionSupported(m_EGLDisplay,"EGL_IMG_context_priority")) { ai32ContextAttribs[i++] = EGL_CONTEXT_PRIORITY_LEVEL_IMG; switch(m_pShell->PVRShellGet(prefPriority)) { case 0: ai32ContextAttribs[i++] = EGL_CONTEXT_PRIORITY_LOW_IMG; break; case 1: ai32ContextAttribs[i++] = EGL_CONTEXT_PRIORITY_MEDIUM_IMG; break; default:ai32ContextAttribs[i++] = EGL_CONTEXT_PRIORITY_HIGH_IMG; } } #endif ai32ContextAttribs[i] = EGL_NONE; m_EGLContext = eglCreateContext(m_EGLDisplay, m_EGLConfig, NULL, ai32ContextAttribs); if(m_EGLContext == EGL_NO_CONTEXT) { if(m_iRequestedConfig > 0) { // We failed to create a context m_pShell->PVRShellSet(prefExitMessage, "PVRShell: Unable to create a context\n"); return false; } else if(m_pShell->m_pShellData->bNeedPbuffer) { // Disable P-buffer and try again m_pShell->m_pShellData->bNeedPbuffer = false; } else if(m_pShell->m_pShellData->bNeedStencilBuffer) { // Disable Stencil Buffer and try again m_pShell->m_pShellData->bNeedStencilBuffer = false; } else if(m_pShell->m_pShellData->nFSAAMode > 0) { // Still failing, reduce the mode of AA and try again --m_pShell->m_pShellData->nFSAAMode; } else { m_pShell->PVRShellSet(prefExitMessage, "PVRShell: Unable to create a context\n"); return false; } } } while(m_EGLContext == EGL_NO_CONTEXT); #if defined(__QNXNTO__) int format = SCREEN_FORMAT_RGBX8888; if(screen_set_window_property_iv((_screen_window*) m_NWT, SCREEN_PROPERTY_FORMAT, &format)) { m_pShell->PVRShellSet(prefExitMessage, "PVRShell: Failed to set window property SCREEN_PROPERTY_FORMAT\n"); return false; } #if defined(BUILD_OGLES2) int usage = SCREEN_USAGE_OPENGL_ES2; #else #if defined(BUILD_OGLES) int usage = SCREEN_USAGE_OPENGL_ES1; #else #if defined(BUILD_OVG) int usage = SCREEN_USAGE_OPENVG; #endif #endif #endif if(screen_set_window_property_iv((_screen_window*) m_NWT, SCREEN_PROPERTY_USAGE, &usage)) { m_pShell->PVRShellSet(prefExitMessage, "PVRShell: Failed to set window property SCREEN_PROPERTY_USAGE\n"); return false; } if(screen_create_window_buffers((_screen_window*) m_NWT, 2)) { m_pShell->PVRShellSet(prefExitMessage, "PVRShell: Failed to create window buffers\n"); return false; } #endif EGLint attrib_list[16]; int i = 0; #if defined(EGL_VERSION_1_2) if(m_pShell->m_pShellData->bNeedAlphaFormatPre) // The default is EGL_ALPHA_FORMAT_NONPRE { attrib_list[i++] = EGL_ALPHA_FORMAT; attrib_list[i++] = EGL_ALPHA_FORMAT_PRE; } #endif // Terminate the attribute list with EGL_NONE attrib_list[i] = EGL_NONE; if(m_pShell->m_pShellData->bNeedPixmap) { m_pShell->PVRShellOutputDebug("InitAPI() Using pixmaps, about to create egl surface\n"); m_EGLWindow = eglCreatePixmapSurface(m_EGLDisplay, m_EGLConfig, m_NPT, attrib_list); } else { #if defined(ANDROID) EGLint visualID; eglGetConfigAttrib(m_EGLDisplay, m_EGLConfig, EGL_NATIVE_VISUAL_ID, &visualID); // Change the format of our window to match our config ANativeWindow_setBuffersGeometry(m_NWT, 0, 0, visualID); #endif m_EGLWindow = eglCreateWindowSurface(m_EGLDisplay, m_EGLConfig, m_NWT, attrib_list); // If we have failed to create a surface then try using Null if(m_EGLWindow == EGL_NO_SURFACE) { m_EGLWindow = eglCreateWindowSurface(m_EGLDisplay, m_EGLConfig, NULL, attrib_list); } } if (m_EGLWindow == EGL_NO_SURFACE) { m_pShell->PVRShellSet(prefExitMessage, "PVRShell: Unable to create surface\n"); return false; } if (!eglMakeCurrent(m_EGLDisplay, m_EGLWindow, m_EGLWindow, m_EGLContext)) { #ifdef EGL_VERSION_1_3 if((eglGetError() == EGL_CONTEXT_LOST)) #else if((eglGetError() == EGL_CONTEXT_LOST_IMG) && m_bPowerManagementSupported) #endif { bDone = false; } else { m_pShell->PVRShellSet(prefExitMessage, "PVRShell: Unable to make context current\n"); return false; } } } while(!bDone); /* Get correct screen width and height and save them into m_pShell->m_pShellData->nShellDimX and m_pShell->m_pShellData->nShellDimY */ eglQuerySurface(m_EGLDisplay, m_EGLWindow, EGL_WIDTH, (EGLint*)&m_pShell->m_pShellData->nShellDimX ); eglQuerySurface(m_EGLDisplay, m_EGLWindow, EGL_HEIGHT, (EGLint*)&m_pShell->m_pShellData->nShellDimY ); #if defined(ANDROID) && !defined(BUILD_OVG) glViewport(0,0,m_pShell->m_pShellData->nShellDimX, m_pShell->m_pShellData->nShellDimY); #endif /* Done - activate requested features */ ApiActivatePreferences(); return true; }