Commit 1bd7dd45 by Cooper Partin Committed by Jamie Madill

Added 16-bit formats to GLConfigs to reduce offscreen texture memory usage.

BUG=angleproject:1042 Change-Id: I7024bd47601a21b08cafbf6460d512151b53d035 Reviewed-on: https://chromium-review.googlesource.com/277002Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 54c34e06
...@@ -31,7 +31,7 @@ class SwapChainD3D : angle::NonCopyable ...@@ -31,7 +31,7 @@ class SwapChainD3D : angle::NonCopyable
{ {
public: public:
SwapChainD3D(rx::NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) SwapChainD3D(rx::NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
: mNativeWindow(nativeWindow), mBackBufferFormat(backBufferFormat), mDepthBufferFormat(depthBufferFormat), mShareHandle(shareHandle) : mNativeWindow(nativeWindow), mOffscreenRenderTargetFormat(backBufferFormat), mDepthBufferFormat(depthBufferFormat), mShareHandle(shareHandle)
{ {
} }
...@@ -45,14 +45,14 @@ class SwapChainD3D : angle::NonCopyable ...@@ -45,14 +45,14 @@ class SwapChainD3D : angle::NonCopyable
virtual RenderTargetD3D *getColorRenderTarget() = 0; virtual RenderTargetD3D *getColorRenderTarget() = 0;
virtual RenderTargetD3D *getDepthStencilRenderTarget() = 0; virtual RenderTargetD3D *getDepthStencilRenderTarget() = 0;
GLenum GetBackBufferInternalFormat() const { return mBackBufferFormat; } GLenum GetRenderTargetInternalFormat() const { return mOffscreenRenderTargetFormat; }
GLenum GetDepthBufferInternalFormat() const { return mDepthBufferFormat; } GLenum GetDepthBufferInternalFormat() const { return mDepthBufferFormat; }
HANDLE getShareHandle() { return mShareHandle; } HANDLE getShareHandle() { return mShareHandle; }
protected: protected:
rx::NativeWindow mNativeWindow; // Handler for the Window that the surface is created for. rx::NativeWindow mNativeWindow; // Handler for the Window that the surface is created for.
const GLenum mBackBufferFormat; const GLenum mOffscreenRenderTargetFormat;
const GLenum mDepthBufferFormat; const GLenum mDepthBufferFormat;
HANDLE mShareHandle; HANDLE mShareHandle;
......
...@@ -346,7 +346,7 @@ GLsizei SurfaceRenderTarget11::getDepth() const ...@@ -346,7 +346,7 @@ GLsizei SurfaceRenderTarget11::getDepth() const
GLenum SurfaceRenderTarget11::getInternalFormat() const GLenum SurfaceRenderTarget11::getInternalFormat() const
{ {
return (mDepth ? mSwapChain->GetDepthBufferInternalFormat() : mSwapChain->GetBackBufferInternalFormat()); return (mDepth ? mSwapChain->GetDepthBufferInternalFormat() : mSwapChain->GetRenderTargetInternalFormat());
} }
GLsizei SurfaceRenderTarget11::getSamples() const GLsizei SurfaceRenderTarget11::getSamples() const
......
...@@ -702,8 +702,13 @@ egl::ConfigSet Renderer11::generateConfigs() const ...@@ -702,8 +702,13 @@ egl::ConfigSet Renderer11::generateConfigs() const
{ {
static const GLenum colorBufferFormats[] = static const GLenum colorBufferFormats[] =
{ {
// 32-bit supported formats
GL_BGRA8_EXT, GL_BGRA8_EXT,
GL_RGBA8_OES, GL_RGBA8_OES,
// 16-bit supported formats
GL_RGBA4,
GL_RGB5_A1,
GL_RGB565,
}; };
static const GLenum depthStencilBufferFormats[] = static const GLenum depthStencilBufferFormats[] =
......
...@@ -112,7 +112,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei ...@@ -112,7 +112,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
releaseOffscreenTexture(); releaseOffscreenTexture();
const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mBackBufferFormat, mRenderer->getRenderer11DeviceCaps()); const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mOffscreenRenderTargetFormat, mRenderer->getRenderer11DeviceCaps());
// If the app passed in a share handle, open the resource // If the app passed in a share handle, open the resource
// See EGL_ANGLE_d3d_share_handle_client_buffer // See EGL_ANGLE_d3d_share_handle_client_buffer
...@@ -358,8 +358,7 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight) ...@@ -358,8 +358,7 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
return EGL_BAD_ALLOC; return EGL_BAD_ALLOC;
} }
const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mBackBufferFormat, mRenderer->getRenderer11DeviceCaps()); result = mSwapChain->ResizeBuffers(desc.BufferCount, backbufferWidth, backbufferHeight, getSwapChainNativeFormat(), 0);
result = mSwapChain->ResizeBuffers(desc.BufferCount, backbufferWidth, backbufferHeight, backbufferFormatInfo.texFormat, 0);
if (FAILED(result)) if (FAILED(result))
{ {
...@@ -393,6 +392,13 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight) ...@@ -393,6 +392,13 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
return resetOffscreenTexture(backbufferWidth, backbufferHeight); return resetOffscreenTexture(backbufferWidth, backbufferHeight);
} }
DXGI_FORMAT SwapChain11::getSwapChainNativeFormat() const
{
// Return a render target format for offscreen rendering is supported by IDXGISwapChain.
// MSDN https://msdn.microsoft.com/en-us/library/windows/desktop/bb173064(v=vs.85).aspx
return (mOffscreenRenderTargetFormat == GL_BGRA8_EXT) ? DXGI_FORMAT_B8G8R8A8_UNORM : DXGI_FORMAT_R8G8B8A8_UNORM;
}
EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swapInterval) EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swapInterval)
{ {
TRACE_EVENT0("gpu.angle", "SwapChain11::reset"); TRACE_EVENT0("gpu.angle", "SwapChain11::reset");
...@@ -426,10 +432,8 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap ...@@ -426,10 +432,8 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap
if (mNativeWindow.getNativeWindow()) if (mNativeWindow.getNativeWindow())
{ {
const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mBackBufferFormat, mRenderer->getRenderer11DeviceCaps());
HRESULT result = mNativeWindow.createSwapChain(device, mRenderer->getDxgiFactory(), HRESULT result = mNativeWindow.createSwapChain(device, mRenderer->getDxgiFactory(),
backbufferFormatInfo.texFormat, getSwapChainNativeFormat(),
backbufferWidth, backbufferHeight, &mSwapChain); backbufferWidth, backbufferHeight, &mSwapChain);
if (FAILED(result)) if (FAILED(result))
......
...@@ -48,6 +48,7 @@ class SwapChain11 : public SwapChainD3D ...@@ -48,6 +48,7 @@ class SwapChain11 : public SwapChainD3D
void initPassThroughResources(); void initPassThroughResources();
void releaseOffscreenTexture(); void releaseOffscreenTexture();
EGLint resetOffscreenTexture(int backbufferWidth, int backbufferHeight); EGLint resetOffscreenTexture(int backbufferWidth, int backbufferHeight);
DXGI_FORMAT getSwapChainNativeFormat() const;
Renderer11 *mRenderer; Renderer11 *mRenderer;
EGLint mHeight; EGLint mHeight;
......
...@@ -698,7 +698,7 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, SwapChain11 *swap ...@@ -698,7 +698,7 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, SwapChain11 *swap
mTextureHeight = texDesc.Height; mTextureHeight = texDesc.Height;
mTextureDepth = 1; mTextureDepth = 1;
mInternalFormat = swapchain->GetBackBufferInternalFormat(); mInternalFormat = swapchain->GetRenderTargetInternalFormat();
ID3D11ShaderResourceView *srv = swapchain->getRenderTargetShaderResource(); ID3D11ShaderResourceView *srv = swapchain->getRenderTargetShaderResource();
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
......
...@@ -111,7 +111,7 @@ GLsizei SurfaceRenderTarget9::getDepth() const ...@@ -111,7 +111,7 @@ GLsizei SurfaceRenderTarget9::getDepth() const
GLenum SurfaceRenderTarget9::getInternalFormat() const GLenum SurfaceRenderTarget9::getInternalFormat() const
{ {
return (mDepth ? mSwapChain->GetDepthBufferInternalFormat() : mSwapChain->GetBackBufferInternalFormat()); return (mDepth ? mSwapChain->GetDepthBufferInternalFormat() : mSwapChain->GetRenderTargetInternalFormat());
} }
GLsizei SurfaceRenderTarget9::getSamples() const GLsizei SurfaceRenderTarget9::getSamples() const
......
...@@ -104,7 +104,7 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI ...@@ -104,7 +104,7 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI
pShareHandle = &mShareHandle; pShareHandle = &mShareHandle;
} }
const d3d9::TextureFormat &backBufferd3dFormatInfo = d3d9::GetTextureFormatInfo(mBackBufferFormat); const d3d9::TextureFormat &backBufferd3dFormatInfo = d3d9::GetTextureFormatInfo(mOffscreenRenderTargetFormat);
result = device->CreateTexture(backbufferWidth, backbufferHeight, 1, D3DUSAGE_RENDERTARGET, result = device->CreateTexture(backbufferWidth, backbufferHeight, 1, D3DUSAGE_RENDERTARGET,
backBufferd3dFormatInfo.texFormat, D3DPOOL_DEFAULT, &mOffscreenTexture, backBufferd3dFormatInfo.texFormat, D3DPOOL_DEFAULT, &mOffscreenTexture,
pShareHandle); pShareHandle);
......
...@@ -105,7 +105,7 @@ TextureStorage9_2D::TextureStorage9_2D(Renderer9 *renderer, SwapChain9 *swapchai ...@@ -105,7 +105,7 @@ TextureStorage9_2D::TextureStorage9_2D(Renderer9 *renderer, SwapChain9 *swapchai
mTexture = surfaceTexture; mTexture = surfaceTexture;
mMipLevels = surfaceTexture->GetLevelCount(); mMipLevels = surfaceTexture->GetLevelCount();
mInternalFormat = swapchain->GetBackBufferInternalFormat(); mInternalFormat = swapchain->GetRenderTargetInternalFormat();
D3DSURFACE_DESC surfaceDesc; D3DSURFACE_DESC surfaceDesc;
surfaceTexture->GetLevelDesc(0, &surfaceDesc); surfaceTexture->GetLevelDesc(0, &surfaceDesc);
......
...@@ -77,7 +77,7 @@ class EGLSurfaceTest : public testing::Test ...@@ -77,7 +77,7 @@ class EGLSurfaceTest : public testing::Test
ASSERT_TRUE(mWindowSurface == EGL_NO_SURFACE && mContext == EGL_NO_CONTEXT); ASSERT_TRUE(mWindowSurface == EGL_NO_SURFACE && mContext == EGL_NO_CONTEXT);
} }
void initializeSurface(EGLenum platformType) void initializeDisplay(EGLenum platformType)
{ {
PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(eglGetProcAddress("eglGetPlatformDisplayEXT")); PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(eglGetProcAddress("eglGetPlatformDisplayEXT"));
ASSERT_TRUE(eglGetPlatformDisplayEXT != nullptr); ASSERT_TRUE(eglGetPlatformDisplayEXT != nullptr);
...@@ -105,21 +105,11 @@ class EGLSurfaceTest : public testing::Test ...@@ -105,21 +105,11 @@ class EGLSurfaceTest : public testing::Test
eglBindAPI(EGL_OPENGL_ES_API); eglBindAPI(EGL_OPENGL_ES_API);
ASSERT_TRUE(eglGetError() == EGL_SUCCESS); ASSERT_TRUE(eglGetError() == EGL_SUCCESS);
}
const EGLint configAttributes[] = void initializeSurface(EGLConfig config)
{ {
EGL_RED_SIZE, EGL_DONT_CARE, mConfig = config;
EGL_GREEN_SIZE, EGL_DONT_CARE,
EGL_BLUE_SIZE, EGL_DONT_CARE,
EGL_ALPHA_SIZE, EGL_DONT_CARE,
EGL_DEPTH_SIZE, EGL_DONT_CARE,
EGL_STENCIL_SIZE, EGL_DONT_CARE,
EGL_SAMPLE_BUFFERS, 0,
EGL_NONE
};
EGLint configCount;
ASSERT_TRUE(eglChooseConfig(mDisplay, configAttributes, &mConfig, 1, &configCount) || (configCount != 1) == EGL_TRUE);
std::vector<EGLint> surfaceAttributes; std::vector<EGLint> surfaceAttributes;
surfaceAttributes.push_back(EGL_NONE); surfaceAttributes.push_back(EGL_NONE);
...@@ -144,6 +134,81 @@ class EGLSurfaceTest : public testing::Test ...@@ -144,6 +134,81 @@ class EGLSurfaceTest : public testing::Test
ASSERT_TRUE(eglGetError() == EGL_SUCCESS); ASSERT_TRUE(eglGetError() == EGL_SUCCESS);
} }
void initializeSurfaceWithDefaultConfig()
{
const EGLint configAttributes[] =
{
EGL_RED_SIZE, EGL_DONT_CARE,
EGL_GREEN_SIZE, EGL_DONT_CARE,
EGL_BLUE_SIZE, EGL_DONT_CARE,
EGL_ALPHA_SIZE, EGL_DONT_CARE,
EGL_DEPTH_SIZE, EGL_DONT_CARE,
EGL_STENCIL_SIZE, EGL_DONT_CARE,
EGL_SAMPLE_BUFFERS, 0,
EGL_NONE
};
EGLint configCount;
EGLConfig config;
ASSERT_TRUE(eglChooseConfig(mDisplay, configAttributes, &config, 1, &configCount) || (configCount != 1) == EGL_TRUE);
initializeSurface(config);
}
GLuint createProgram()
{
const std::string testVertexShaderSource = SHADER_SOURCE
(
attribute highp vec4 position;
void main(void)
{
gl_Position = position;
}
);
const std::string testFragmentShaderSource = SHADER_SOURCE
(
void main(void)
{
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
);
return CompileProgram(testVertexShaderSource, testFragmentShaderSource);
}
void drawWithProgram(GLuint program)
{
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
GLint positionLocation = glGetAttribLocation(program, "position");
glUseProgram(program);
const GLfloat vertices[] =
{
-1.0f, 1.0f, 0.5f,
-1.0f, -1.0f, 0.5f,
1.0f, -1.0f, 0.5f,
-1.0f, 1.0f, 0.5f,
1.0f, -1.0f, 0.5f,
1.0f, 1.0f, 0.5f,
};
glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, vertices);
glEnableVertexAttribArray(positionLocation);
glDrawArrays(GL_TRIANGLES, 0, 6);
glDisableVertexAttribArray(positionLocation);
glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, NULL);
EXPECT_PIXEL_EQ(mOSWindow->getWidth() / 2, mOSWindow->getHeight() / 2, 255, 0, 0, 255);
}
void runMessageLoopTest(EGLSurface secondSurface, EGLContext secondContext) void runMessageLoopTest(EGLSurface secondSurface, EGLContext secondContext)
{ {
eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext); eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
...@@ -192,7 +257,8 @@ TEST_F(EGLSurfaceTest, MessageLoopBug) ...@@ -192,7 +257,8 @@ TEST_F(EGLSurfaceTest, MessageLoopBug)
return; return;
} }
initializeSurface(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE); initializeDisplay(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE);
initializeSurfaceWithDefaultConfig();
runMessageLoopTest(EGL_NO_SURFACE, EGL_NO_CONTEXT); runMessageLoopTest(EGL_NO_SURFACE, EGL_NO_CONTEXT);
} }
...@@ -208,7 +274,8 @@ TEST_F(EGLSurfaceTest, MessageLoopBugContext) ...@@ -208,7 +274,8 @@ TEST_F(EGLSurfaceTest, MessageLoopBugContext)
return; return;
} }
initializeSurface(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE); initializeDisplay(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE);
initializeSurfaceWithDefaultConfig();
runMessageLoopTest(mPbufferSurface, mSecondContext); runMessageLoopTest(mPbufferSurface, mSecondContext);
} }
...@@ -216,7 +283,8 @@ TEST_F(EGLSurfaceTest, MessageLoopBugContext) ...@@ -216,7 +283,8 @@ TEST_F(EGLSurfaceTest, MessageLoopBugContext)
// Test a bug where calling makeCurrent twice would release the surface // Test a bug where calling makeCurrent twice would release the surface
TEST_F(EGLSurfaceTest, MakeCurrentTwice) TEST_F(EGLSurfaceTest, MakeCurrentTwice)
{ {
initializeSurface(EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE); initializeDisplay(EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE);
initializeSurfaceWithDefaultConfig();
eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext); eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
ASSERT_TRUE(eglGetError() == EGL_SUCCESS); ASSERT_TRUE(eglGetError() == EGL_SUCCESS);
...@@ -238,7 +306,8 @@ TEST_F(EGLSurfaceTest, ResizeD3DWindow) ...@@ -238,7 +306,8 @@ TEST_F(EGLSurfaceTest, ResizeD3DWindow)
return; return;
} }
initializeSurface(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE); initializeDisplay(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE);
initializeSurfaceWithDefaultConfig();
eglSwapBuffers(mDisplay, mWindowSurface); eglSwapBuffers(mDisplay, mWindowSurface);
ASSERT_EGL_SUCCESS(); ASSERT_EGL_SUCCESS();
...@@ -269,4 +338,108 @@ TEST_F(EGLSurfaceTest, ResizeD3DWindow) ...@@ -269,4 +338,108 @@ TEST_F(EGLSurfaceTest, ResizeD3DWindow)
ASSERT_EQ(64, height); ASSERT_EQ(64, height);
} }
// Test creating a surface that supports a EGLConfig with 16bit
// support GL_RGB565
TEST_F(EGLSurfaceTest, CreateWithEGLConfig5650Support)
{
const EGLint configAttributes[] =
{
EGL_RED_SIZE, 5,
EGL_GREEN_SIZE, 6,
EGL_BLUE_SIZE, 5,
EGL_ALPHA_SIZE, 0,
EGL_DEPTH_SIZE, 0,
EGL_STENCIL_SIZE, 0,
EGL_SAMPLE_BUFFERS, 0,
EGL_NONE
};
initializeDisplay(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE);
EGLConfig config;
if (EGLWindow::FindEGLConfig(mDisplay, configAttributes, &config) == EGL_FALSE)
{
std::cout << "EGLConfig for a GL_RGB565 surface is not supported, skipping test" << std::endl;
return;
}
initializeSurface(config);
eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
ASSERT_TRUE(eglGetError() == EGL_SUCCESS);
GLuint program = createProgram();
drawWithProgram(program);
EXPECT_GL_NO_ERROR();
glDeleteProgram(program);
}
// Test creating a surface that supports a EGLConfig with 16bit
// support GL_RGBA4
TEST_F(EGLSurfaceTest, CreateWithEGLConfig4444Support)
{
const EGLint configAttributes[] =
{
EGL_RED_SIZE, 4,
EGL_GREEN_SIZE, 4,
EGL_BLUE_SIZE, 4,
EGL_ALPHA_SIZE, 4,
EGL_DEPTH_SIZE, 0,
EGL_STENCIL_SIZE, 0,
EGL_SAMPLE_BUFFERS, 0,
EGL_NONE
};
initializeDisplay(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE);
EGLConfig config;
if (EGLWindow::FindEGLConfig(mDisplay, configAttributes, &config) == EGL_FALSE)
{
std::cout << "EGLConfig for a GL_RGBA4 surface is not supported, skipping test" << std::endl;
return;
}
initializeSurface(config);
eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
ASSERT_TRUE(eglGetError() == EGL_SUCCESS);
GLuint program = createProgram();
drawWithProgram(program);
EXPECT_GL_NO_ERROR();
glDeleteProgram(program);
}
// Test creating a surface that supports a EGLConfig with 16bit
// support GL_RGB5_A1
TEST_F(EGLSurfaceTest, CreateWithEGLConfig5551Support)
{
const EGLint configAttributes[] =
{
EGL_RED_SIZE, 5,
EGL_GREEN_SIZE, 5,
EGL_BLUE_SIZE, 5,
EGL_ALPHA_SIZE, 1,
EGL_DEPTH_SIZE, 0,
EGL_STENCIL_SIZE, 0,
EGL_SAMPLE_BUFFERS, 0,
EGL_NONE
};
initializeDisplay(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE);
EGLConfig config;
if (EGLWindow::FindEGLConfig(mDisplay, configAttributes, &config) == EGL_FALSE)
{
std::cout << "EGLConfig for a GL_RGB5_A1 surface is not supported, skipping test" << std::endl;
return;
}
initializeSurface(config);
eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
ASSERT_TRUE(eglGetError() == EGL_SUCCESS);
GLuint program = createProgram();
drawWithProgram(program);
EXPECT_GL_NO_ERROR();
glDeleteProgram(program);
}
} }
...@@ -263,3 +263,36 @@ bool EGLWindow::isGLInitialized() const ...@@ -263,3 +263,36 @@ bool EGLWindow::isGLInitialized() const
mContext != EGL_NO_CONTEXT && mContext != EGL_NO_CONTEXT &&
mDisplay != EGL_NO_DISPLAY; mDisplay != EGL_NO_DISPLAY;
} }
// Find an EGLConfig that is an exact match for the specified attributes. EGL_FALSE is returned if
// the EGLConfig is found. This indicates that the EGLConfig is not supported.
EGLBoolean EGLWindow::FindEGLConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *config)
{
EGLint numConfigs = 0;
eglGetConfigs(dpy, nullptr, 0, &numConfigs);
std::vector<EGLConfig> allConfigs(numConfigs);
eglGetConfigs(dpy, allConfigs.data(), allConfigs.size(), &numConfigs);
for (size_t i = 0; i < allConfigs.size(); i++)
{
bool matchFound = true;
for (const EGLint *curAttrib = attrib_list; curAttrib[0] != EGL_NONE; curAttrib += 2)
{
EGLint actualValue = EGL_DONT_CARE;
eglGetConfigAttrib(dpy, allConfigs[i], curAttrib[0], &actualValue);
if (curAttrib[1] != actualValue)
{
matchFound = false;
break;
}
}
if (matchFound)
{
*config = allConfigs[i];
return EGL_TRUE;
}
}
return EGL_FALSE;
}
...@@ -65,6 +65,8 @@ class EGLWindow : angle::NonCopyable ...@@ -65,6 +65,8 @@ class EGLWindow : angle::NonCopyable
void setMultisample(bool multisample) { mMultisample = multisample; } void setMultisample(bool multisample) { mMultisample = multisample; }
void setSwapInterval(EGLint swapInterval) { mSwapInterval = swapInterval; } void setSwapInterval(EGLint swapInterval) { mSwapInterval = swapInterval; }
static EGLBoolean FindEGLConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *config);
void swap(); void swap();
EGLint getClientVersion() const { return mClientVersion; } EGLint getClientVersion() const { return mClientVersion; }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment