summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-02 22:22:40 +0000
committerapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-02 22:22:40 +0000
commitc007aa019c6ef8d09b14db05453e06764a929c83 (patch)
treee3c9c0136801def0b36e1ace4ac16c1814160284
parent59aa617b508b067ddaf5c3190c08ee86751d1906 (diff)
downloadchromium_src-c007aa019c6ef8d09b14db05453e06764a929c83.zip
chromium_src-c007aa019c6ef8d09b14db05453e06764a929c83.tar.gz
chromium_src-c007aa019c6ef8d09b14db05453e06764a929c83.tar.bz2
GPU process SwapBuffers from child to parent context calls glFlush before invoking SwapBuffers callback.
This is required for the side effects of the swap to be guaranteed visible to teh parent context. Also fixed the back buffer clearing to work with ANGLE. TEST=try, change the default clear color to test that the back buffer was actually cleared. BUG=none Review URL: http://codereview.chromium.org/3170035 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@58413 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc118
1 files changed, 56 insertions, 62 deletions
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index fe03abe..f13fc47 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -848,6 +848,9 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
void ClearUnclearedRenderbuffers(
GLenum target, FramebufferManager::FramebufferInfo* info);
+ // Restore all GL state that affects clearing.
+ void RestoreClearState();
+
// Remembers the state of some capabilities.
void SetCapabilityState(GLenum cap, bool enabled);
@@ -1057,7 +1060,8 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
// Wrapper for glValidateProgram.
void DoValidateProgram(GLuint program_client_id);
- void DoCopyTextureToParentTexture(GLuint client_texture_id, GLuint parent_client_texture_id);
+ void DoCopyTextureToParentTexture(GLuint client_texture_id,
+ GLuint parent_client_texture_id);
// Gets the number of values that will be returned by glGetXXX. Returns
// false if pname is unknown.
@@ -1168,13 +1172,6 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
// The GL context this decoder renders to on behalf of the client.
scoped_ptr<gfx::GLContext> context_;
- // A GLContext that is kept in its default state. It is used to perform
- // operations that should not be dependent on client set GLContext state, like
- // clearing a render buffer when it is created.
- // TODO(apatrick): Decoders in the same ContextGroup could potentially share
- // the same default GL context.
- scoped_ptr<gfx::GLContext> default_context_;
-
// A parent decoder can access this decoders saved offscreen frame buffer.
// The parent pointer is reset if the parent is destroyed.
base::WeakPtr<GLES2DecoderImpl> parent_;
@@ -1336,15 +1333,6 @@ ScopedFrameBufferBinder::~ScopedFrameBufferBinder() {
decoder_->RestoreCurrentFramebufferBindings();
}
-ScopedDefaultGLContext::ScopedDefaultGLContext(GLES2DecoderImpl* decoder)
- : decoder_(decoder) {
- decoder_->default_context_->MakeCurrent();
-}
-
-ScopedDefaultGLContext::~ScopedDefaultGLContext() {
- decoder_->context_->MakeCurrent();
-}
-
Texture::Texture(GLES2DecoderImpl* decoder)
: decoder_(decoder),
id_(0) {
@@ -1568,15 +1556,6 @@ bool GLES2DecoderImpl::Initialize(gfx::GLContext* context,
// Take ownership of the GLContext.
context_.reset(context);
- // Create a GL context that is kept in a default state and shares a namespace
- // with the main GL context.
- default_context_.reset(gfx::GLContext::CreateOffscreenGLContext(
- context_.get()));
- if (!default_context_.get()) {
- Destroy();
- return false;
- }
-
// Keep only a weak pointer to the parent so we don't unmap its client
// frame buffer after it has been destroyed.
if (parent)
@@ -1826,6 +1805,14 @@ void GLES2DecoderImpl::DeleteTexturesHelper(
}
}
+static bool IsAngle() {
+#if defined(OS_WIN)
+ return gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2;
+#else
+ return false;
+#endif
+}
+
// } // anonymous namespace
bool GLES2DecoderImpl::MakeCurrent() {
@@ -2016,18 +2003,19 @@ bool GLES2DecoderImpl::UpdateOffscreenFrameBufferSize() {
return false;
}
- // TODO(apatrick): Fix this once ANGLE supports shared contexts.
- // Clear offscreen frame buffer to its initial state. Use default GL context
- // to ensure clear is not affected by client set state.
- if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
- ScopedDefaultGLContext scoped_context(this);
- glBindFramebufferEXT(GL_FRAMEBUFFER,
- offscreen_target_frame_buffer_->id());
+ // Clear the target frame buffer.
+ {
+ ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
+ glClearColor(0, 1, 0, 1);
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ glClearStencil(0);
+ glStencilMaskSeparate(GL_FRONT, GL_TRUE);
+ glStencilMaskSeparate(GL_BACK, GL_TRUE);
+ glClearDepth(0);
+ glDepthMask(GL_TRUE);
+ glDisable(GL_SCISSOR_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
- glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
-
- if (glGetError() != GL_NO_ERROR)
- return false;
+ RestoreClearState();
}
if (parent_) {
@@ -2064,18 +2052,15 @@ bool GLES2DecoderImpl::UpdateOffscreenFrameBufferSize() {
return false;
}
- // TODO(apatrick): Fix this once ANGLE supports shared contexts.
- // Clear the saved offscreen color texture. Use default GL context
- // to ensure clear is not affected by client set state.
- if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
- ScopedDefaultGLContext scoped_context(this);
- glBindFramebufferEXT(GL_FRAMEBUFFER,
- offscreen_target_frame_buffer_->id());
+ // Clear the offscreen color texture.
+ {
+ ScopedFrameBufferBinder binder(this,
+ offscreen_target_frame_buffer_->id());
+ glClearColor(0, 0, 0, 0);
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ glDisable(GL_SCISSOR_TEST);
glClear(GL_COLOR_BUFFER_BIT);
- glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
-
- if (glGetError() != GL_NO_ERROR)
- return false;
+ RestoreClearState();
}
// Re-attach the offscreen render texture to the target frame buffer.
@@ -2150,11 +2135,6 @@ void GLES2DecoderImpl::Destroy() {
context_->Destroy();
context_.reset();
}
-
- if (default_context_.get()) {
- default_context_->Destroy();
- default_context_.reset();
- }
}
void GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
@@ -2164,10 +2144,14 @@ void GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
pending_offscreen_size_ = size;
}
-void GLES2DecoderImpl::DoCopyTextureToParentTexture(GLuint client_texture_id, GLuint parent_client_texture_id) {
+void GLES2DecoderImpl::DoCopyTextureToParentTexture(
+ GLuint client_texture_id,
+ GLuint parent_client_texture_id) {
if (parent_) {
- TextureManager::TextureInfo* texture = texture_manager()->GetTextureInfo(client_texture_id);
- TextureManager::TextureInfo* parent_texture = parent_->texture_manager()->GetTextureInfo(parent_client_texture_id);
+ TextureManager::TextureInfo* texture = texture_manager()->GetTextureInfo(
+ client_texture_id);
+ TextureManager::TextureInfo* parent_texture =
+ parent_->texture_manager()->GetTextureInfo(parent_client_texture_id);
if (!texture || !parent_texture) {
current_decoder_error_ = error::kInvalidArguments;
return;
@@ -2184,7 +2168,7 @@ void GLES2DecoderImpl::DoCopyTextureToParentTexture(GLuint client_texture_id, GL
glCopyTexImage2D(GL_TEXTURE_2D,
0, // level
GL_RGBA,
- 0, 0, // x, y
+ 0, 0, // x, y
width,
height,
0); // border
@@ -3038,7 +3022,14 @@ void GLES2DecoderImpl::ClearUnclearedRenderbuffers(
info->MarkAttachedRenderbuffersAsCleared();
- // reset clear color
+ RestoreClearState();
+
+ if (target == GL_READ_FRAMEBUFFER_EXT) {
+ // TODO(gman): rebind draw.
+ }
+}
+
+void GLES2DecoderImpl::RestoreClearState() {
glClearColor(clear_red_, clear_green_, clear_blue_, clear_alpha_);
glColorMask(mask_red_, mask_green_, mask_blue_, mask_alpha_);
glClearStencil(clear_stencil_);
@@ -3049,10 +3040,6 @@ void GLES2DecoderImpl::ClearUnclearedRenderbuffers(
if (enable_scissor_test_) {
glEnable(GL_SCISSOR_TEST);
}
-
- if (target == GL_READ_FRAMEBUFFER_EXT) {
- // TODO(gman): rebind draw.
- }
}
GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
@@ -5332,10 +5319,17 @@ error::Error GLES2DecoderImpl::HandleSwapBuffers(
return error::kLostContext;
if (parent_) {
+ // Copy the target frame buffer to the saved offscreen texture.
ScopedFrameBufferBinder binder(this,
offscreen_target_frame_buffer_->id());
offscreen_saved_color_texture_->Copy(
offscreen_saved_color_texture_->size());
+
+ // Ensure the side effects of the copy are visible to the parent context.
+ // There is no need to do this for ANGLE because it uses a single D3D
+ // device for all contexts.
+ if (!IsAngle())
+ glFlush();
}
} else {
context_->SwapBuffers();