summaryrefslogtreecommitdiffstats
path: root/gpu/command_buffer/service
diff options
context:
space:
mode:
authorbacker@chromium.org <backer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-25 17:50:00 +0000
committerbacker@chromium.org <backer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-25 17:50:00 +0000
commit7ff86b93008f19aaddac784323ce4117d6725aa0 (patch)
treead24f5498395eb8a98232134ee23d092b7ee1240 /gpu/command_buffer/service
parent49952775c67f130e37d3d892f17657f56efbbe7a (diff)
downloadchromium_src-7ff86b93008f19aaddac784323ce4117d6725aa0.zip
chromium_src-7ff86b93008f19aaddac784323ce4117d6725aa0.tar.gz
chromium_src-7ff86b93008f19aaddac784323ce4117d6725aa0.tar.bz2
Resize synchronization for Linux.
This patch makes synchronous calls from the GPU to the Browser process to resize windows. It must be synchronous because we must be sure when the resize happens, it must be initiated by the GPU because we have to time the resize with GL drawing, and the resize must be done by the Browser because of how GDK/GTK is structured. Specifically, when a window that a GL context is associated with is resized, the back buffer gets blanked. So it is important that we synchronize the resize with the drawing to the back buffer. On Linux, the X window that we are drawing to is wrapped in a GdkWindow inside the Browser process. GDK/GTK assumes that all changes to the window happen via GDK calls. In particular, the size of the window is cached inside the GdkWindow object so that it does not have to make a call to the X server in order to get window geometry. Unfortunately, this necessitates resizing the window inside of the Browser process. For more discussion of this approach and (some unsuccessfully attempted) alternatives see https://docs.google.com/a/google.com/document/d/1ZNouL-X_Ml1x8sqy-sofz63pDAeo36VWi_yQihaE2YI/edit?hl=en This patch set uncovered another bug: - open in two separate windows http://webkit.org/blog/386/3d-transforms/ and http://webkit.org/blog-files/3d-transforms/poster-circle.html - resize the former until it is smallish - watch the root layer of the former show up as the root layer of the later. To my knowledge, this is first trigger of this bug. If and when this patch is accepted, I will file the bug. BUG=http://code.google.com/p/chromium/issues/detail?id=54430 TEST=Go to http://peter.sh/2010/06/chromium-now-features-gpu-acceleration-and-css-3d-transforms/ . Rotate Z with the slider to trigger the compositor. Resize the window. The resize may be janky (we're uploading large textures), but it should display properly. Contributed by backer@chromium.org Review URL: http://codereview.chromium.org/5105006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@67416 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu/command_buffer/service')
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc16
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.h4
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_mock.h1
-rw-r--r--gpu/command_buffer/service/gpu_processor.cc4
-rw-r--r--gpu/command_buffer/service/gpu_processor.h4
5 files changed, 27 insertions, 2 deletions
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index fbb6ca4..d120744 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -677,6 +677,7 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
virtual gfx::GLContext* GetGLContext() { return context_.get(); }
virtual ContextGroup* GetContextGroup() { return group_.get(); }
+ virtual void SetResizeCallback(Callback1<gfx::Size>::Type* callback);
virtual void SetSwapBuffersCallback(Callback0::Type* callback);
virtual bool GetServiceTextureId(uint32 client_texture_id,
uint32* service_texture_id);
@@ -1424,6 +1425,7 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
scoped_ptr<Texture> offscreen_saved_color_texture_;
GLenum offscreen_saved_color_format_;
+ scoped_ptr<Callback1<gfx::Size>::Type> resize_callback_;
scoped_ptr<Callback0::Type> swap_buffers_callback_;
// The last error message set.
@@ -2422,6 +2424,10 @@ bool GLES2DecoderImpl::UpdateOffscreenFrameBufferSize() {
return true;
}
+void GLES2DecoderImpl::SetResizeCallback(Callback1<gfx::Size>::Type* callback) {
+ resize_callback_.reset(callback);
+}
+
void GLES2DecoderImpl::SetSwapBuffersCallback(Callback0::Type* callback) {
swap_buffers_callback_.reset(callback);
}
@@ -2552,8 +2558,14 @@ void GLES2DecoderImpl::DoCopyTextureToParentTextureCHROMIUM(
}
void GLES2DecoderImpl::DoResizeCHROMIUM(GLuint width, GLuint height) {
- gfx::Size size(width, height);
- context_->SetSize(size);
+#if defined(OS_LINUX)
+ // Make sure that we are done drawing to the back buffer before resizing.
+ glFinish();
+#endif
+ if (resize_callback_.get()) {
+ gfx::Size size(width, height);
+ resize_callback_->Run(size);
+ }
}
const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.h b/gpu/command_buffer/service/gles2_cmd_decoder.h
index 5c8b735..eddd7fe 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.h
@@ -89,6 +89,10 @@ class GLES2Decoder : public CommonDecoder {
// Gets the associated ContextGroup
virtual ContextGroup* GetContextGroup() = 0;
+ // Sets a callback which is called when a glResizeCHROMIUM command
+ // is processed.
+ virtual void SetResizeCallback(Callback1<gfx::Size>::Type* callback) = 0;
+
// Sets a callback which is called when a SwapBuffers command is processed.
virtual void SetSwapBuffersCallback(Callback0::Type* callback) = 0;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
index bee0202..a0e5c7e 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
@@ -44,6 +44,7 @@ class MockGLES2Decoder : public GLES2Decoder {
MOCK_METHOD0(GetGLES2Util, GLES2Util*());
MOCK_METHOD0(GetGLContext, gfx::GLContext*());
MOCK_METHOD0(GetContextGroup, ContextGroup*());
+ MOCK_METHOD1(SetResizeCallback, void(Callback1<gfx::Size>::Type*));
MOCK_METHOD1(SetSwapBuffersCallback, void(Callback0::Type*));
MOCK_METHOD3(DoCommand, error::Error(unsigned int command,
unsigned int arg_count,
diff --git a/gpu/command_buffer/service/gpu_processor.cc b/gpu/command_buffer/service/gpu_processor.cc
index d32cb62..275f3cb 100644
--- a/gpu/command_buffer/service/gpu_processor.cc
+++ b/gpu/command_buffer/service/gpu_processor.cc
@@ -145,6 +145,10 @@ void GPUProcessor::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
decoder_->ResizeOffscreenFrameBuffer(size);
}
+void GPUProcessor::SetResizeCallback(Callback1<gfx::Size>::Type* callback) {
+ decoder_->SetResizeCallback(callback);
+}
+
void GPUProcessor::SetSwapBuffersCallback(
Callback0::Type* callback) {
wrapped_swap_buffers_callback_.reset(callback);
diff --git a/gpu/command_buffer/service/gpu_processor.h b/gpu/command_buffer/service/gpu_processor.h
index 986ab03..247c4c5 100644
--- a/gpu/command_buffer/service/gpu_processor.h
+++ b/gpu/command_buffer/service/gpu_processor.h
@@ -87,6 +87,10 @@ class GPUProcessor : public CommandBufferEngine {
virtual uint64 GetSurfaceId();
#endif
+ // Sets a callback that is called when a glResizeCHROMIUM command
+ // is processed.
+ virtual void SetResizeCallback(Callback1<gfx::Size>::Type* callback);
+
// Sets a callback which is called when a SwapBuffers command is processed.
// Must be called after Initialize().
// It is not defined on which thread this callback is called.