Error Display::createContext(const Config *configuration, gl::Context *shareContext, const AttributeMap &attribs, gl::Context **outContext) { ASSERT(isInitialized()); if (mImplementation->testDeviceLost()) { Error error = restoreLostDevice(); if (error.isError()) { return error; } } gl::Context *context = nullptr; Error error = mImplementation->createContext(configuration, shareContext, attribs, &context); if (error.isError()) { return error; } ASSERT(context != nullptr); mContextSet.insert(context); ASSERT(outContext != nullptr); *outContext = context; return Error(EGL_SUCCESS); }
EGLSurface Display::createWindowSurface(HWND window, EGLConfig config, const EGLint *attribList) { const Config *configuration = mConfigSet.get(config); EGLint postSubBufferSupported = EGL_FALSE; if (attribList) { while (*attribList != EGL_NONE) { switch (attribList[0]) { case EGL_RENDER_BUFFER: switch (attribList[1]) { case EGL_BACK_BUFFER: break; case EGL_SINGLE_BUFFER: return error(EGL_BAD_MATCH, EGL_NO_SURFACE); // Rendering directly to front buffer not supported default: return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); } break; case EGL_POST_SUB_BUFFER_SUPPORTED_NV: postSubBufferSupported = attribList[1]; break; case EGL_VG_COLORSPACE: return error(EGL_BAD_MATCH, EGL_NO_SURFACE); case EGL_VG_ALPHA_FORMAT: return error(EGL_BAD_MATCH, EGL_NO_SURFACE); default: return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); } attribList += 2; } } if (hasExistingWindowSurface(window)) { return error(EGL_BAD_ALLOC, EGL_NO_SURFACE); } if (testDeviceLost()) { if (!restoreLostDevice()) return EGL_NO_SURFACE; } Surface *surface = new Surface(this, configuration, window, postSubBufferSupported); if (!surface->initialize()) { delete surface; return EGL_NO_SURFACE; } mSurfaceSet.insert(surface); return success(surface); }
Error Display::createPixmapSurface(const Config *configuration, NativePixmapType nativePixmap, const AttributeMap &attribs, Surface **outSurface) { ASSERT(isInitialized()); if (mImplementation->testDeviceLost()) { Error error = restoreLostDevice(); if (error.isError()) { return error; } } rx::SurfaceImpl *surfaceImpl = mImplementation->createPixmapSurface(configuration, nativePixmap, attribs); ASSERT(surfaceImpl != nullptr); Error error = surfaceImpl->initialize(); if (error.isError()) { SafeDelete(surfaceImpl); return error; } Surface *surface = new Surface(surfaceImpl, EGL_PIXMAP_BIT, configuration, attribs); mImplementation->getSurfaceSet().insert(surface); ASSERT(outSurface != nullptr); *outSurface = surface; return Error(EGL_SUCCESS); }
Error Display::createWindowSurface(const Config *configuration, EGLNativeWindowType window, const AttributeMap &attribs, Surface **outSurface) { if (mImplementation->testDeviceLost()) { Error error = restoreLostDevice(); if (error.isError()) { return error; } } rx::SurfaceImpl *surfaceImpl = mImplementation->createWindowSurface(configuration, window, attribs); ASSERT(surfaceImpl != nullptr); Error error = surfaceImpl->initialize(); if (error.isError()) { SafeDelete(surfaceImpl); return error; } Surface *surface = new Surface(surfaceImpl, EGL_WINDOW_BIT, configuration, attribs); mImplementation->getSurfaceSet().insert(surface); WindowSurfaceMap *windowSurfaces = GetWindowSurfaces(); ASSERT(windowSurfaces && windowSurfaces->find(window) == windowSurfaces->end()); windowSurfaces->insert(std::make_pair(window, surface)); ASSERT(outSurface != nullptr); *outSurface = surface; return Error(EGL_SUCCESS); }
Error Display::createPbufferFromClientBuffer(const Config *configuration, EGLClientBuffer shareHandle, const AttributeMap &attribs, Surface **outSurface) { ASSERT(isInitialized()); if (mImplementation->testDeviceLost()) { Error error = restoreLostDevice(); if (error.isError()) { return error; } } rx::SurfaceImpl *surfaceImpl = mImplementation->createPbufferFromClientBuffer(configuration, shareHandle, attribs); ASSERT(surfaceImpl != nullptr); Error error = surfaceImpl->initialize(); if (error.isError()) { SafeDelete(surfaceImpl); return error; } Surface *surface = new Surface(surfaceImpl, EGL_PBUFFER_BIT, configuration, attribs); mImplementation->getSurfaceSet().insert(surface); ASSERT(outSurface != nullptr); *outSurface = surface; return Error(EGL_SUCCESS); }
Error Display::createImage(gl::Context *context, EGLenum target, EGLClientBuffer buffer, const AttributeMap &attribs, Image **outImage) { ASSERT(isInitialized()); if (mImplementation->testDeviceLost()) { Error error = restoreLostDevice(); if (error.isError()) { return error; } } egl::ImageSibling *sibling = nullptr; if (IsTextureTarget(target)) { sibling = context->getTexture(egl_gl::EGLClientBufferToGLObjectHandle(buffer)); } else if (IsRenderbufferTarget(target)) { sibling = context->getRenderbuffer(egl_gl::EGLClientBufferToGLObjectHandle(buffer)); } else { UNREACHABLE(); } ASSERT(sibling != nullptr); rx::ImageImpl *imageImpl = mImplementation->createImage(target, sibling, attribs); ASSERT(imageImpl != nullptr); Error error = imageImpl->initialize(); if (error.isError()) { return error; } Image *image = new Image(imageImpl, target, sibling, attribs); ASSERT(outImage != nullptr); *outImage = image; // Add this image to the list of all images and hold a ref to it. image->addRef(); mImageSet.insert(image); return Error(EGL_SUCCESS); }
EGLContext Display::createContext(EGLConfig configHandle, const gl::Context *shareContext, bool notifyResets, bool robustAccess) { if (!mRenderer) { return NULL; } else if (mRenderer->testDeviceLost(false)) // Lost device { if (!restoreLostDevice()) return NULL; } gl::Context *context = glCreateContext(shareContext, mRenderer, notifyResets, robustAccess); mContextSet.insert(context); return context; }
Error Display::createPbufferSurface(const Config *configuration, const AttributeMap &attribs, Surface **outSurface) { ASSERT(isInitialized()); if (mImplementation->testDeviceLost()) { ANGLE_TRY(restoreLostDevice()); } std::unique_ptr<Surface> surface(new PbufferSurface(mImplementation, configuration, attribs)); ANGLE_TRY(surface->initialize()); ASSERT(outSurface != nullptr); *outSurface = surface.release(); mImplementation->getSurfaceSet().insert(*outSurface); return egl::Error(EGL_SUCCESS); }
Error Display::createContext(const Config *configuration, gl::Context *shareContext, const AttributeMap &attribs, gl::Context **outContext) { ASSERT(isInitialized()); if (mImplementation->testDeviceLost()) { ANGLE_TRY(restoreLostDevice()); } gl::Context *context = new gl::Context(mImplementation, configuration, shareContext, attribs); ASSERT(context != nullptr); mContextSet.insert(context); ASSERT(outContext != nullptr); *outContext = context; return egl::Error(EGL_SUCCESS); }
Error Display::createImage(gl::Context *context, EGLenum target, EGLClientBuffer buffer, const AttributeMap &attribs, Image **outImage) { ASSERT(isInitialized()); if (mImplementation->testDeviceLost()) { Error error = restoreLostDevice(); if (error.isError()) { return error; } } UNIMPLEMENTED(); return Error(EGL_SUCCESS); }
Error Display::createWindowSurface(const Config *configuration, EGLNativeWindowType window, const AttributeMap &attribs, Surface **outSurface) { if (mImplementation->testDeviceLost()) { ANGLE_TRY(restoreLostDevice()); } std::unique_ptr<Surface> surface( new WindowSurface(mImplementation, configuration, window, attribs)); ANGLE_TRY(surface->initialize()); ASSERT(outSurface != nullptr); *outSurface = surface.release(); mImplementation->getSurfaceSet().insert(*outSurface); WindowSurfaceMap *windowSurfaces = GetWindowSurfaces(); ASSERT(windowSurfaces && windowSurfaces->find(window) == windowSurfaces->end()); windowSurfaces->insert(std::make_pair(window, *outSurface)); return egl::Error(EGL_SUCCESS); }
EGLContext Display::createContext(EGLConfig configHandle, const gl::Context *shareContext, bool notifyResets, bool robustAccess) { if (!mDevice) { if (!createDevice()) { return NULL; } } else if (testDeviceLost()) // Lost device { if (!restoreLostDevice()) return NULL; } const egl::Config *config = mConfigSet.get(configHandle); gl::Context *context = glCreateContext(config, shareContext, notifyResets, robustAccess); mContextSet.insert(context); mDeviceLost = false; return context; }
EGLContext Display::createContext(EGLConfig configHandle, EGLint clientVersion, const gl::Context *shareContext, bool notifyResets, bool robustAccess) { if (!mRenderer) { return EGL_NO_CONTEXT; } else if (mRenderer->testDeviceLost(false)) // Lost device { if (!restoreLostDevice()) { return error(EGL_CONTEXT_LOST, EGL_NO_CONTEXT); } } if (clientVersion > 2 && mRenderer->getMajorShaderModel() < 4) { return error(EGL_BAD_CONFIG, EGL_NO_CONTEXT); } gl::Context *context = glCreateContext(clientVersion, shareContext, mRenderer, notifyResets, robustAccess); mContextSet.insert(context); return success(context); }
EGLSurface Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList) { EGLint width = 0, height = 0; EGLenum textureFormat = EGL_NO_TEXTURE; EGLenum textureTarget = EGL_NO_TEXTURE; const Config *configuration = mConfigSet.get(config); if (attribList) { while (*attribList != EGL_NONE) { switch (attribList[0]) { case EGL_WIDTH: width = attribList[1]; break; case EGL_HEIGHT: height = attribList[1]; break; case EGL_LARGEST_PBUFFER: if (attribList[1] != EGL_FALSE) UNIMPLEMENTED(); // FIXME break; case EGL_TEXTURE_FORMAT: switch (attribList[1]) { case EGL_NO_TEXTURE: case EGL_TEXTURE_RGB: case EGL_TEXTURE_RGBA: textureFormat = attribList[1]; break; default: return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); } break; case EGL_TEXTURE_TARGET: switch (attribList[1]) { case EGL_NO_TEXTURE: case EGL_TEXTURE_2D: textureTarget = attribList[1]; break; default: return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); } break; case EGL_MIPMAP_TEXTURE: if (attribList[1] != EGL_FALSE) return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); break; case EGL_VG_COLORSPACE: return error(EGL_BAD_MATCH, EGL_NO_SURFACE); case EGL_VG_ALPHA_FORMAT: return error(EGL_BAD_MATCH, EGL_NO_SURFACE); default: return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); } attribList += 2; } } if (width < 0 || height < 0) { return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE); } if (width == 0 || height == 0) { return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); } if (textureFormat != EGL_NO_TEXTURE && !mRenderer->getRendererExtensions().textureNPOT && (!gl::isPow2(width) || !gl::isPow2(height))) { return error(EGL_BAD_MATCH, EGL_NO_SURFACE); } if ((textureFormat != EGL_NO_TEXTURE && textureTarget == EGL_NO_TEXTURE) || (textureFormat == EGL_NO_TEXTURE && textureTarget != EGL_NO_TEXTURE)) { return error(EGL_BAD_MATCH, EGL_NO_SURFACE); } if (!(configuration->mSurfaceType & EGL_PBUFFER_BIT)) { return error(EGL_BAD_MATCH, EGL_NO_SURFACE); } if ((textureFormat == EGL_TEXTURE_RGB && configuration->mBindToTextureRGB != EGL_TRUE) || (textureFormat == EGL_TEXTURE_RGBA && configuration->mBindToTextureRGBA != EGL_TRUE)) { return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); } if (mRenderer->testDeviceLost(false)) { if (!restoreLostDevice()) return EGL_NO_SURFACE; } Surface *surface = new Surface(this, configuration, shareHandle, width, height, textureFormat, textureTarget); if (!surface->initialize()) { delete surface; return EGL_NO_SURFACE; } mSurfaceSet.insert(surface); return success(surface); }