Loading opengl/include/EGL/eglext.h +5 −0 Original line number Diff line number Diff line Loading @@ -625,6 +625,11 @@ typedef EGLClientBuffer (EGLAPIENTRYP PFNEGLGETNATIVECLIENTBUFFERANDROID) (const #define EGL_MUTABLE_RENDER_BUFFER_BIT_KHR 0x1000 #endif #ifndef EGL_KHR_no_config_context #define EGL_KHR_no_config_context 1 #define EGL_NO_CONFIG_KHR EGL_CAST(EGLConfig,0) #endif /* EGL_KHR_no_config_context */ #ifndef EGL_ANDROID_get_frame_timestamps #define EGL_ANDROID_get_frame_timestamps 1 #define EGL_TIMESTAMPS_ANDROID 0x3430 Loading opengl/libs/EGL/eglApi.cpp +79 −15 Original line number Diff line number Diff line Loading @@ -473,6 +473,45 @@ static android_dataspace modifyBufferDataspace( android_dataspace dataSpace, return dataSpace; } static EGLBoolean getColorSpaceAttribute(egl_display_ptr dp, const EGLint* attrib_list, EGLint& colorSpace, android_dataspace& dataSpace) { colorSpace = EGL_GL_COLORSPACE_LINEAR_KHR; dataSpace = HAL_DATASPACE_UNKNOWN; if (attrib_list && dp->haveExtension("EGL_KHR_gl_colorspace")) { for (const EGLint* attr = attrib_list; *attr != EGL_NONE; attr += 2) { if (*attr == EGL_GL_COLORSPACE_KHR) { colorSpace = attr[1]; bool found = false; // Verify that color space is allowed if (colorSpace == EGL_GL_COLORSPACE_SRGB_KHR || colorSpace == EGL_GL_COLORSPACE_LINEAR_KHR) { found = true; } else if (colorSpace == EGL_EXT_gl_colorspace_bt2020_linear && dp->haveExtension("EGL_EXT_gl_colorspace_bt2020_linear")) { found = true; } else if (colorSpace == EGL_EXT_gl_colorspace_bt2020_pq && dp->haveExtension("EGL_EXT_gl_colorspace_bt2020_pq")) { found = true; } else if (colorSpace == EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT && dp->haveExtension("EGL_EXT_gl_colorspace_scrgb_linear")) { found = true; } else if (colorSpace == EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT && dp->haveExtension("EGL_EXT_gl_colorspace_display_p3_linear")) { found = true; } else if (colorSpace == EGL_GL_COLORSPACE_DISPLAY_P3_EXT && dp->haveExtension("EGL_EXT_gl_colorspace_display_p3")) { found = true; } if (!found) { return false; } } } dataSpace = modifyBufferDataspace(dataSpace, colorSpace); } return true; } EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list) Loading Loading @@ -513,7 +552,8 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config, &componentType); EGLint format; android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN; EGLint colorSpace; android_dataspace dataSpace; EGLint a = 0; EGLint r, g, b; r = g = b = 0; Loading Loading @@ -550,12 +590,9 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config, } // now select a corresponding sRGB format if needed if (attrib_list && dp->haveExtension("EGL_KHR_gl_colorspace")) { for (const EGLint* attr = attrib_list; *attr != EGL_NONE; attr += 2) { if (*attr == EGL_GL_COLORSPACE_KHR) { dataSpace = modifyBufferDataspace(dataSpace, *(attr+1)); } } if (!getColorSpaceAttribute(dp, attrib_list, colorSpace, dataSpace)) { ALOGE("error invalid colorspace: %d", colorSpace); return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); } if (format != 0) { Loading Loading @@ -586,8 +623,8 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config, EGLSurface surface = cnx->egl.eglCreateWindowSurface( iDpy, config, window, attrib_list); if (surface != EGL_NO_SURFACE) { egl_surface_t* s = new egl_surface_t(dp.get(), config, window, surface, cnx); egl_surface_t* s = new egl_surface_t(dp.get(), config, window, surface, colorSpace, cnx); return s; } Loading @@ -606,12 +643,19 @@ EGLSurface eglCreatePixmapSurface( EGLDisplay dpy, EGLConfig config, egl_connection_t* cnx = NULL; egl_display_ptr dp = validate_display_connection(dpy, cnx); EGLint colorSpace; android_dataspace dataSpace; if (dp) { // now select a corresponding sRGB format if needed if (!getColorSpaceAttribute(dp, attrib_list, colorSpace, dataSpace)) { ALOGE("error invalid colorspace: %d", colorSpace); return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); } EGLSurface surface = cnx->egl.eglCreatePixmapSurface( dp->disp.dpy, config, pixmap, attrib_list); if (surface != EGL_NO_SURFACE) { egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL, surface, cnx); egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL, surface, colorSpace, cnx); return s; } } Loading @@ -625,12 +669,19 @@ EGLSurface eglCreatePbufferSurface( EGLDisplay dpy, EGLConfig config, egl_connection_t* cnx = NULL; egl_display_ptr dp = validate_display_connection(dpy, cnx); EGLint colorSpace; android_dataspace dataSpace; if (dp) { // now select a corresponding sRGB format if needed if (!getColorSpaceAttribute(dp, attrib_list, colorSpace, dataSpace)) { ALOGE("error invalid colorspace: %d", colorSpace); return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); } EGLSurface surface = cnx->egl.eglCreatePbufferSurface( dp->disp.dpy, config, attrib_list); if (surface != EGL_NO_SURFACE) { egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL, surface, cnx); egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL, surface, colorSpace, cnx); return s; } } Loading Loading @@ -669,6 +720,10 @@ EGLBoolean eglQuerySurface( EGLDisplay dpy, EGLSurface surface, return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE); egl_surface_t const * const s = get_surface(surface); if (attribute == EGL_GL_COLORSPACE_KHR) { *value = s->getColorSpace(); return EGL_TRUE; } return s->cnx->egl.eglQuerySurface( dp->disp.dpy, s->surface, attribute, value); } Loading Loading @@ -1708,13 +1763,22 @@ EGLSurface eglCreateStreamProducerSurfaceKHR(EGLDisplay dpy, EGLConfig config, egl_display_ptr dp = validate_display(dpy); if (!dp) return EGL_NO_SURFACE; EGLint colorSpace = EGL_GL_COLORSPACE_LINEAR_KHR; android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN; // TODO: Probably need to update EGL_KHR_stream_producer_eglsurface to // indicate support for EGL_GL_COLORSPACE_KHR. // now select a corresponding sRGB format if needed if (!getColorSpaceAttribute(dp, attrib_list, colorSpace, dataSpace)) { ALOGE("error invalid colorspace: %d", colorSpace); return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); } egl_connection_t* const cnx = &gEGLImpl; if (cnx->dso && cnx->egl.eglCreateStreamProducerSurfaceKHR) { EGLSurface surface = cnx->egl.eglCreateStreamProducerSurfaceKHR( dp->disp.dpy, config, stream, attrib_list); if (surface != EGL_NO_SURFACE) { egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL, surface, cnx); egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL, surface, colorSpace, cnx); return s; } } Loading opengl/libs/EGL/egl_object.cpp +9 −6 Original line number Diff line number Diff line Loading @@ -55,12 +55,15 @@ bool egl_object_t::get(egl_display_t const* display, egl_object_t* object) { // ---------------------------------------------------------------------------- egl_surface_t::egl_surface_t(egl_display_t* dpy, EGLConfig config, EGLNativeWindowType win, EGLSurface surface, egl_connection_t const* cnx) : egl_object_t(dpy), surface(surface), config(config), win(win), cnx(cnx), connected(true) { egl_surface_t::egl_surface_t(egl_display_t* dpy, EGLConfig config, EGLNativeWindowType win, EGLSurface surface, EGLint colorSpace, egl_connection_t const* cnx) : egl_object_t(dpy), surface(surface), config(config), win(win), cnx(cnx), connected(true), colorSpace(colorSpace) { if (win) { win->incStrong(this); } Loading opengl/libs/EGL/egl_object.h +4 −3 Original line number Diff line number Diff line Loading @@ -131,12 +131,12 @@ protected: public: typedef egl_object_t::LocalRef<egl_surface_t, EGLSurface> Ref; egl_surface_t(egl_display_t* dpy, EGLConfig config, EGLNativeWindowType win, EGLSurface surface, egl_connection_t const* cnx); egl_surface_t(egl_display_t* dpy, EGLConfig config, EGLNativeWindowType win, EGLSurface surface, EGLint colorSpace, egl_connection_t const* cnx); ANativeWindow* getNativeWindow() { return win; } ANativeWindow* getNativeWindow() const { return win; } EGLint getColorSpace() const { return colorSpace; } // Try to keep the order of these fields and size unchanged. It's not public API, but // it's not hard to imagine native games accessing them. Loading @@ -149,6 +149,7 @@ public: private: bool connected; void disconnect(); EGLint colorSpace; }; class egl_context_t: public egl_object_t { Loading opengl/tests/EGLTest/EGL_test.cpp +93 −26 Original line number Diff line number Diff line Loading @@ -28,18 +28,17 @@ #include <gui/IGraphicBufferConsumer.h> #include <gui/BufferQueue.h> #define PIXEL_FORMAT_FLOAT "EGL_EXT_pixel_format_float" bool hasEglPixelFormatFloat() { EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); bool hasEglExtension(EGLDisplay dpy, const char* extensionName) { const char* exts = eglQueryString(dpy, EGL_EXTENSIONS); size_t cropExtLen = strlen(PIXEL_FORMAT_FLOAT); size_t cropExtLen = strlen(extensionName); size_t extsLen = strlen(exts); bool equal = !strcmp(PIXEL_FORMAT_FLOAT, exts); bool atStart = !strncmp(PIXEL_FORMAT_FLOAT " ", exts, cropExtLen + 1); bool equal = !strcmp(extensionName, exts); android::String8 extString(extensionName); android::String8 space(" "); bool atStart = !strncmp(extString + space, exts, cropExtLen + 1); bool atEnd = (cropExtLen + 1) < extsLen && !strcmp(" " PIXEL_FORMAT_FLOAT, exts + extsLen - (cropExtLen + 1)); bool inMiddle = strstr(exts, " " PIXEL_FORMAT_FLOAT " "); !strcmp(space + extString, exts + extsLen - (cropExtLen + 1)); bool inMiddle = strstr(exts, space + extString + space); return equal || atStart || atEnd || inMiddle; } Loading Loading @@ -203,23 +202,20 @@ TEST_F(EGLTest, EGLConfigFP16) { return; } ASSERT_TRUE(hasEglPixelFormatFloat()); EGLint attrs[] = {EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_RED_SIZE, 16, EGL_GREEN_SIZE, 16, EGL_BLUE_SIZE, 16, EGL_ALPHA_SIZE, 16, EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT, EGL_NONE}; ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_pixel_format_float")); EGLint attrs[] = { // clang-format off EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_RED_SIZE, 16, EGL_GREEN_SIZE, 16, EGL_BLUE_SIZE, 16, EGL_ALPHA_SIZE, 16, EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT, EGL_NONE, EGL_NONE // clang-format on }; success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs); ASSERT_EQ(EGL_UNSIGNED_TRUE, success); ASSERT_EQ(1, numConfigs); Loading Loading @@ -250,6 +246,77 @@ TEST_F(EGLTest, EGLConfigFP16) { void onSidebandStreamChanged() override {} }; sp<IGraphicBufferProducer> producer; sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer); consumer->consumerConnect(new DummyConsumer, false); sp<Surface> mSTC = new Surface(producer); sp<ANativeWindow> mANW = mSTC; EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), NULL); ASSERT_EQ(EGL_SUCCESS, eglGetError()); ASSERT_NE(EGL_NO_SURFACE, eglSurface); EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface)); } // Emulate what a native application would do to create a // 10:10:10:2 surface. TEST_F(EGLTest, EGLConfig1010102) { EGLint numConfigs; EGLConfig config; EGLBoolean success; if (!hasWideColorDisplay) { // skip this test if device does not have wide-color display return; } EGLint attrs[] = { // clang-format off EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT, EGL_RED_SIZE, 10, EGL_GREEN_SIZE, 10, EGL_BLUE_SIZE, 10, EGL_ALPHA_SIZE, 2, EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT, EGL_NONE, EGL_NONE // clang-format on }; success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs); ASSERT_EQ(EGL_UNSIGNED_TRUE, success); ASSERT_EQ(1, numConfigs); EGLint components[4]; EGLint value; eglGetConfigAttrib(mEglDisplay, config, EGL_CONFIG_ID, &value); success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]); ASSERT_EQ(EGL_UNSIGNED_TRUE, success); ASSERT_EQ(EGL_SUCCESS, eglGetError()); success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]); ASSERT_EQ(EGL_UNSIGNED_TRUE, success); ASSERT_EQ(EGL_SUCCESS, eglGetError()); success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]); ASSERT_EQ(EGL_UNSIGNED_TRUE, success); ASSERT_EQ(EGL_SUCCESS, eglGetError()); success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]); ASSERT_EQ(EGL_UNSIGNED_TRUE, success); ASSERT_EQ(EGL_SUCCESS, eglGetError()); EXPECT_EQ(components[0], 10); EXPECT_EQ(components[1], 10); EXPECT_EQ(components[2], 10); EXPECT_EQ(components[3], 2); struct DummyConsumer : public BnConsumerListener { void onFrameAvailable(const BufferItem& /* item */) override {} void onBuffersReleased() override {} void onSidebandStreamChanged() override {} }; // Create a EGLSurface sp<IGraphicBufferProducer> producer; sp<IGraphicBufferConsumer> consumer; Loading Loading
opengl/include/EGL/eglext.h +5 −0 Original line number Diff line number Diff line Loading @@ -625,6 +625,11 @@ typedef EGLClientBuffer (EGLAPIENTRYP PFNEGLGETNATIVECLIENTBUFFERANDROID) (const #define EGL_MUTABLE_RENDER_BUFFER_BIT_KHR 0x1000 #endif #ifndef EGL_KHR_no_config_context #define EGL_KHR_no_config_context 1 #define EGL_NO_CONFIG_KHR EGL_CAST(EGLConfig,0) #endif /* EGL_KHR_no_config_context */ #ifndef EGL_ANDROID_get_frame_timestamps #define EGL_ANDROID_get_frame_timestamps 1 #define EGL_TIMESTAMPS_ANDROID 0x3430 Loading
opengl/libs/EGL/eglApi.cpp +79 −15 Original line number Diff line number Diff line Loading @@ -473,6 +473,45 @@ static android_dataspace modifyBufferDataspace( android_dataspace dataSpace, return dataSpace; } static EGLBoolean getColorSpaceAttribute(egl_display_ptr dp, const EGLint* attrib_list, EGLint& colorSpace, android_dataspace& dataSpace) { colorSpace = EGL_GL_COLORSPACE_LINEAR_KHR; dataSpace = HAL_DATASPACE_UNKNOWN; if (attrib_list && dp->haveExtension("EGL_KHR_gl_colorspace")) { for (const EGLint* attr = attrib_list; *attr != EGL_NONE; attr += 2) { if (*attr == EGL_GL_COLORSPACE_KHR) { colorSpace = attr[1]; bool found = false; // Verify that color space is allowed if (colorSpace == EGL_GL_COLORSPACE_SRGB_KHR || colorSpace == EGL_GL_COLORSPACE_LINEAR_KHR) { found = true; } else if (colorSpace == EGL_EXT_gl_colorspace_bt2020_linear && dp->haveExtension("EGL_EXT_gl_colorspace_bt2020_linear")) { found = true; } else if (colorSpace == EGL_EXT_gl_colorspace_bt2020_pq && dp->haveExtension("EGL_EXT_gl_colorspace_bt2020_pq")) { found = true; } else if (colorSpace == EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT && dp->haveExtension("EGL_EXT_gl_colorspace_scrgb_linear")) { found = true; } else if (colorSpace == EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT && dp->haveExtension("EGL_EXT_gl_colorspace_display_p3_linear")) { found = true; } else if (colorSpace == EGL_GL_COLORSPACE_DISPLAY_P3_EXT && dp->haveExtension("EGL_EXT_gl_colorspace_display_p3")) { found = true; } if (!found) { return false; } } } dataSpace = modifyBufferDataspace(dataSpace, colorSpace); } return true; } EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list) Loading Loading @@ -513,7 +552,8 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config, &componentType); EGLint format; android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN; EGLint colorSpace; android_dataspace dataSpace; EGLint a = 0; EGLint r, g, b; r = g = b = 0; Loading Loading @@ -550,12 +590,9 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config, } // now select a corresponding sRGB format if needed if (attrib_list && dp->haveExtension("EGL_KHR_gl_colorspace")) { for (const EGLint* attr = attrib_list; *attr != EGL_NONE; attr += 2) { if (*attr == EGL_GL_COLORSPACE_KHR) { dataSpace = modifyBufferDataspace(dataSpace, *(attr+1)); } } if (!getColorSpaceAttribute(dp, attrib_list, colorSpace, dataSpace)) { ALOGE("error invalid colorspace: %d", colorSpace); return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); } if (format != 0) { Loading Loading @@ -586,8 +623,8 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config, EGLSurface surface = cnx->egl.eglCreateWindowSurface( iDpy, config, window, attrib_list); if (surface != EGL_NO_SURFACE) { egl_surface_t* s = new egl_surface_t(dp.get(), config, window, surface, cnx); egl_surface_t* s = new egl_surface_t(dp.get(), config, window, surface, colorSpace, cnx); return s; } Loading @@ -606,12 +643,19 @@ EGLSurface eglCreatePixmapSurface( EGLDisplay dpy, EGLConfig config, egl_connection_t* cnx = NULL; egl_display_ptr dp = validate_display_connection(dpy, cnx); EGLint colorSpace; android_dataspace dataSpace; if (dp) { // now select a corresponding sRGB format if needed if (!getColorSpaceAttribute(dp, attrib_list, colorSpace, dataSpace)) { ALOGE("error invalid colorspace: %d", colorSpace); return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); } EGLSurface surface = cnx->egl.eglCreatePixmapSurface( dp->disp.dpy, config, pixmap, attrib_list); if (surface != EGL_NO_SURFACE) { egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL, surface, cnx); egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL, surface, colorSpace, cnx); return s; } } Loading @@ -625,12 +669,19 @@ EGLSurface eglCreatePbufferSurface( EGLDisplay dpy, EGLConfig config, egl_connection_t* cnx = NULL; egl_display_ptr dp = validate_display_connection(dpy, cnx); EGLint colorSpace; android_dataspace dataSpace; if (dp) { // now select a corresponding sRGB format if needed if (!getColorSpaceAttribute(dp, attrib_list, colorSpace, dataSpace)) { ALOGE("error invalid colorspace: %d", colorSpace); return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); } EGLSurface surface = cnx->egl.eglCreatePbufferSurface( dp->disp.dpy, config, attrib_list); if (surface != EGL_NO_SURFACE) { egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL, surface, cnx); egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL, surface, colorSpace, cnx); return s; } } Loading Loading @@ -669,6 +720,10 @@ EGLBoolean eglQuerySurface( EGLDisplay dpy, EGLSurface surface, return setError(EGL_BAD_SURFACE, (EGLBoolean)EGL_FALSE); egl_surface_t const * const s = get_surface(surface); if (attribute == EGL_GL_COLORSPACE_KHR) { *value = s->getColorSpace(); return EGL_TRUE; } return s->cnx->egl.eglQuerySurface( dp->disp.dpy, s->surface, attribute, value); } Loading Loading @@ -1708,13 +1763,22 @@ EGLSurface eglCreateStreamProducerSurfaceKHR(EGLDisplay dpy, EGLConfig config, egl_display_ptr dp = validate_display(dpy); if (!dp) return EGL_NO_SURFACE; EGLint colorSpace = EGL_GL_COLORSPACE_LINEAR_KHR; android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN; // TODO: Probably need to update EGL_KHR_stream_producer_eglsurface to // indicate support for EGL_GL_COLORSPACE_KHR. // now select a corresponding sRGB format if needed if (!getColorSpaceAttribute(dp, attrib_list, colorSpace, dataSpace)) { ALOGE("error invalid colorspace: %d", colorSpace); return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); } egl_connection_t* const cnx = &gEGLImpl; if (cnx->dso && cnx->egl.eglCreateStreamProducerSurfaceKHR) { EGLSurface surface = cnx->egl.eglCreateStreamProducerSurfaceKHR( dp->disp.dpy, config, stream, attrib_list); if (surface != EGL_NO_SURFACE) { egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL, surface, cnx); egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL, surface, colorSpace, cnx); return s; } } Loading
opengl/libs/EGL/egl_object.cpp +9 −6 Original line number Diff line number Diff line Loading @@ -55,12 +55,15 @@ bool egl_object_t::get(egl_display_t const* display, egl_object_t* object) { // ---------------------------------------------------------------------------- egl_surface_t::egl_surface_t(egl_display_t* dpy, EGLConfig config, EGLNativeWindowType win, EGLSurface surface, egl_connection_t const* cnx) : egl_object_t(dpy), surface(surface), config(config), win(win), cnx(cnx), connected(true) { egl_surface_t::egl_surface_t(egl_display_t* dpy, EGLConfig config, EGLNativeWindowType win, EGLSurface surface, EGLint colorSpace, egl_connection_t const* cnx) : egl_object_t(dpy), surface(surface), config(config), win(win), cnx(cnx), connected(true), colorSpace(colorSpace) { if (win) { win->incStrong(this); } Loading
opengl/libs/EGL/egl_object.h +4 −3 Original line number Diff line number Diff line Loading @@ -131,12 +131,12 @@ protected: public: typedef egl_object_t::LocalRef<egl_surface_t, EGLSurface> Ref; egl_surface_t(egl_display_t* dpy, EGLConfig config, EGLNativeWindowType win, EGLSurface surface, egl_connection_t const* cnx); egl_surface_t(egl_display_t* dpy, EGLConfig config, EGLNativeWindowType win, EGLSurface surface, EGLint colorSpace, egl_connection_t const* cnx); ANativeWindow* getNativeWindow() { return win; } ANativeWindow* getNativeWindow() const { return win; } EGLint getColorSpace() const { return colorSpace; } // Try to keep the order of these fields and size unchanged. It's not public API, but // it's not hard to imagine native games accessing them. Loading @@ -149,6 +149,7 @@ public: private: bool connected; void disconnect(); EGLint colorSpace; }; class egl_context_t: public egl_object_t { Loading
opengl/tests/EGLTest/EGL_test.cpp +93 −26 Original line number Diff line number Diff line Loading @@ -28,18 +28,17 @@ #include <gui/IGraphicBufferConsumer.h> #include <gui/BufferQueue.h> #define PIXEL_FORMAT_FLOAT "EGL_EXT_pixel_format_float" bool hasEglPixelFormatFloat() { EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); bool hasEglExtension(EGLDisplay dpy, const char* extensionName) { const char* exts = eglQueryString(dpy, EGL_EXTENSIONS); size_t cropExtLen = strlen(PIXEL_FORMAT_FLOAT); size_t cropExtLen = strlen(extensionName); size_t extsLen = strlen(exts); bool equal = !strcmp(PIXEL_FORMAT_FLOAT, exts); bool atStart = !strncmp(PIXEL_FORMAT_FLOAT " ", exts, cropExtLen + 1); bool equal = !strcmp(extensionName, exts); android::String8 extString(extensionName); android::String8 space(" "); bool atStart = !strncmp(extString + space, exts, cropExtLen + 1); bool atEnd = (cropExtLen + 1) < extsLen && !strcmp(" " PIXEL_FORMAT_FLOAT, exts + extsLen - (cropExtLen + 1)); bool inMiddle = strstr(exts, " " PIXEL_FORMAT_FLOAT " "); !strcmp(space + extString, exts + extsLen - (cropExtLen + 1)); bool inMiddle = strstr(exts, space + extString + space); return equal || atStart || atEnd || inMiddle; } Loading Loading @@ -203,23 +202,20 @@ TEST_F(EGLTest, EGLConfigFP16) { return; } ASSERT_TRUE(hasEglPixelFormatFloat()); EGLint attrs[] = {EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_RED_SIZE, 16, EGL_GREEN_SIZE, 16, EGL_BLUE_SIZE, 16, EGL_ALPHA_SIZE, 16, EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT, EGL_NONE}; ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_EXT_pixel_format_float")); EGLint attrs[] = { // clang-format off EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_RED_SIZE, 16, EGL_GREEN_SIZE, 16, EGL_BLUE_SIZE, 16, EGL_ALPHA_SIZE, 16, EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT, EGL_NONE, EGL_NONE // clang-format on }; success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs); ASSERT_EQ(EGL_UNSIGNED_TRUE, success); ASSERT_EQ(1, numConfigs); Loading Loading @@ -250,6 +246,77 @@ TEST_F(EGLTest, EGLConfigFP16) { void onSidebandStreamChanged() override {} }; sp<IGraphicBufferProducer> producer; sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer); consumer->consumerConnect(new DummyConsumer, false); sp<Surface> mSTC = new Surface(producer); sp<ANativeWindow> mANW = mSTC; EGLSurface eglSurface = eglCreateWindowSurface(mEglDisplay, config, mANW.get(), NULL); ASSERT_EQ(EGL_SUCCESS, eglGetError()); ASSERT_NE(EGL_NO_SURFACE, eglSurface); EXPECT_TRUE(eglDestroySurface(mEglDisplay, eglSurface)); } // Emulate what a native application would do to create a // 10:10:10:2 surface. TEST_F(EGLTest, EGLConfig1010102) { EGLint numConfigs; EGLConfig config; EGLBoolean success; if (!hasWideColorDisplay) { // skip this test if device does not have wide-color display return; } EGLint attrs[] = { // clang-format off EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT, EGL_RED_SIZE, 10, EGL_GREEN_SIZE, 10, EGL_BLUE_SIZE, 10, EGL_ALPHA_SIZE, 2, EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT, EGL_NONE, EGL_NONE // clang-format on }; success = eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs); ASSERT_EQ(EGL_UNSIGNED_TRUE, success); ASSERT_EQ(1, numConfigs); EGLint components[4]; EGLint value; eglGetConfigAttrib(mEglDisplay, config, EGL_CONFIG_ID, &value); success = eglGetConfigAttrib(mEglDisplay, config, EGL_RED_SIZE, &components[0]); ASSERT_EQ(EGL_UNSIGNED_TRUE, success); ASSERT_EQ(EGL_SUCCESS, eglGetError()); success = eglGetConfigAttrib(mEglDisplay, config, EGL_GREEN_SIZE, &components[1]); ASSERT_EQ(EGL_UNSIGNED_TRUE, success); ASSERT_EQ(EGL_SUCCESS, eglGetError()); success = eglGetConfigAttrib(mEglDisplay, config, EGL_BLUE_SIZE, &components[2]); ASSERT_EQ(EGL_UNSIGNED_TRUE, success); ASSERT_EQ(EGL_SUCCESS, eglGetError()); success = eglGetConfigAttrib(mEglDisplay, config, EGL_ALPHA_SIZE, &components[3]); ASSERT_EQ(EGL_UNSIGNED_TRUE, success); ASSERT_EQ(EGL_SUCCESS, eglGetError()); EXPECT_EQ(components[0], 10); EXPECT_EQ(components[1], 10); EXPECT_EQ(components[2], 10); EXPECT_EQ(components[3], 2); struct DummyConsumer : public BnConsumerListener { void onFrameAvailable(const BufferItem& /* item */) override {} void onBuffersReleased() override {} void onSidebandStreamChanged() override {} }; // Create a EGLSurface sp<IGraphicBufferProducer> producer; sp<IGraphicBufferConsumer> consumer; Loading