diff options
author | thakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-05 18:07:26 +0000 |
---|---|---|
committer | thakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-05 18:07:26 +0000 |
commit | ebb090d01ffa509095e49d78f28574b8ed6cb669 (patch) | |
tree | 7d009277cc82c36cf206b3298a92005e1821d950 /chrome/browser | |
parent | 52d60bf31bf6243338d96d8c87158f3a3216c51e (diff) | |
download | chromium_src-ebb090d01ffa509095e49d78f28574b8ed6cb669.zip chromium_src-ebb090d01ffa509095e49d78f28574b8ed6cb669.tar.gz chromium_src-ebb090d01ffa509095e49d78f28574b8ed6cb669.tar.bz2 |
Mac/gpu: Don't show uninitialized surfaces while resizing plugins / composited tabs.
BUG=53165
TEST=Go to http://webkit.org/blog/386/3d-transforms/. Resize window. Watch a youtube video click the "make bigger" button. No garbage should appear. There are still some funky artifacts at the top/right border during resizing caused by clamping the texture instead of filling with white, and sometimes (rarely) the tab flashes black/white but I'd like to tackle that in follow-up CLs. This is already much better than what's in the tree currently.
Review URL: http://codereview.chromium.org/4101002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@65220 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
3 files changed, 45 insertions, 25 deletions
diff --git a/chrome/browser/renderer_host/accelerated_surface_container_mac.cc b/chrome/browser/renderer_host/accelerated_surface_container_mac.cc index ca2a600..7fb2e07 100644 --- a/chrome/browser/renderer_host/accelerated_surface_container_mac.cc +++ b/chrome/browser/renderer_host/accelerated_surface_container_mac.cc @@ -31,18 +31,11 @@ void AcceleratedSurfaceContainerMac::SetSizeAndIOSurface( int32 width, int32 height, uint64 io_surface_identifier) { - surface_.reset(); - surface_id_ = 0; - IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize(); - if (io_surface_support) { - surface_.reset(io_surface_support->IOSurfaceLookup( - static_cast<uint32>(io_surface_identifier))); - if (surface_.get()) - surface_id_ = io_surface_identifier; - EnqueueTextureForDeletion(); - width_ = width; - height_ = height; - } + // Ignore |io_surface_identifier|: The surface hasn't been painted to and + // only contains garbage data. Update the surface in |set_was_painted_to()| + // instead. + width_ = width; + height_ = height; } void AcceleratedSurfaceContainerMac::SetSizeAndTransportDIB( @@ -114,8 +107,8 @@ void AcceleratedSurfaceContainerMac::Draw(CGLContextObj context) { io_surface_support->CGLTexImageIOSurface2D(context, target, GL_RGBA, - width_, - height_, + surface_width_, + surface_height_, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, surface_.get(), @@ -141,6 +134,9 @@ void AcceleratedSurfaceContainerMac::Draw(CGLContextObj context) { } if (texture_) { + int texture_width = io_surface_support ? surface_width_ : width_; + int texture_height = io_surface_support ? surface_height_ : height_; + // TODO(kbr): convert this to use only OpenGL ES 2.0 functionality. // TODO(kbr): may need to pay attention to cutout rects. @@ -149,6 +145,11 @@ void AcceleratedSurfaceContainerMac::Draw(CGLContextObj context) { int clipWidth = clipRect_.width(); int clipHeight = clipRect_.height(); + if (clipX + clipWidth > texture_width) + clipWidth = texture_width - clipX; + if (clipY + clipHeight > texture_height) + clipHeight = texture_height - clipY; + if (opaque_) { // Pepper 3D's output is currently considered opaque even if the // program draws pixels with alpha less than 1. In order to have @@ -179,16 +180,16 @@ void AcceleratedSurfaceContainerMac::Draw(CGLContextObj context) { glEnable(target); glBegin(GL_TRIANGLE_STRIP); - glTexCoord2f(clipX, height_ - clipY); + glTexCoord2f(clipX, texture_height - clipY); glVertex3f(0, 0, 0); - glTexCoord2f(clipX + clipWidth, height_ - clipY); + glTexCoord2f(clipX + clipWidth, texture_height - clipY); glVertex3f(clipWidth, 0, 0); - glTexCoord2f(clipX, height_ - clipY - clipHeight); + glTexCoord2f(clipX, texture_height - clipY - clipHeight); glVertex3f(0, clipHeight, 0); - glTexCoord2f(clipX + clipWidth, height_ - clipY - clipHeight); + glTexCoord2f(clipX + clipWidth, texture_height - clipY - clipHeight); glVertex3f(clipWidth, clipHeight, 0); glEnd(); @@ -197,11 +198,22 @@ void AcceleratedSurfaceContainerMac::Draw(CGLContextObj context) { } void AcceleratedSurfaceContainerMac::set_was_painted_to(uint64 surface_id) { - if (surface_id) { - // Check that only the most current IOSurface allocated for this container - // is painted to. - DCHECK(surface_); - DCHECK_EQ(surface_id, surface_id_); + if (surface_id && (!surface_ || surface_id != surface_id_)) { + // Keep the surface that was most recently painted to around. + if (IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize()) { + CFTypeRef surface = io_surface_support->IOSurfaceLookup( + static_cast<uint32>(surface_id)); + // Can fail if IOSurface with that ID was already released by the + // gpu process or the plugin process. We will get a |set_was_painted_to()| + // message with a new surface soon in that case. + if (surface) { + surface_.reset(surface); + surface_id_ = surface_id; + surface_width_ = io_surface_support->IOSurfaceGetWidth(surface_); + surface_height_ = io_surface_support->IOSurfaceGetHeight(surface_); + EnqueueTextureForDeletion(); + } + } } was_painted_to_ = true; } diff --git a/chrome/browser/renderer_host/accelerated_surface_container_mac.h b/chrome/browser/renderer_host/accelerated_surface_container_mac.h index 243692b..0c343e4 100644 --- a/chrome/browser/renderer_host/accelerated_surface_container_mac.h +++ b/chrome/browser/renderer_host/accelerated_surface_container_mac.h @@ -100,12 +100,17 @@ class AcceleratedSurfaceContainerMac { // The id of |surface_|, or 0 if |surface_| is NULL. uint64 surface_id_; + // The width and height of the io surface. During resizing, this is different + // from |width_| and |height_|. + int32 surface_width_; + int32 surface_height_; + // The TransportDIB which is used in pre-10.6 systems where the IOSurface // API is not supported. This is a weak reference to the actual TransportDIB // whic is owned by the GPU process. scoped_ptr<TransportDIB> transport_dib_; - // The width and height of the surface. + // The width and height of the container. int32 width_; int32 height_; diff --git a/chrome/browser/renderer_host/accelerated_surface_container_manager_mac.cc b/chrome/browser/renderer_host/accelerated_surface_container_manager_mac.cc index 77be3ac..b123f76 100644 --- a/chrome/browser/renderer_host/accelerated_surface_container_manager_mac.cc +++ b/chrome/browser/renderer_host/accelerated_surface_container_manager_mac.cc @@ -99,7 +99,10 @@ void AcceleratedSurfaceContainerManagerMac::Draw(CGLContextObj context, AutoLock lock(lock_); glColorMask(true, true, true, true); - glClearColor(0, 0, 0, 0); + // Should match the clear color of RenderWidgetHostViewMac. + glClearColor(255, 255, 255, 255); + // TODO(thakis): Clearing the whole color buffer is wasteful, since most of + // it is overwritten by the surface. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDisable(GL_DEPTH_TEST); glDisable(GL_BLEND); |