diff options
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/renderer_host/backing_store.h | 13 | ||||
-rw-r--r-- | chrome/browser/renderer_host/backing_store_mac.mm | 89 |
2 files changed, 68 insertions, 34 deletions
diff --git a/chrome/browser/renderer_host/backing_store.h b/chrome/browser/renderer_host/backing_store.h index 6278884..8130498 100644 --- a/chrome/browser/renderer_host/backing_store.h +++ b/chrome/browser/renderer_host/backing_store.h @@ -105,6 +105,19 @@ class BackingStore { const gfx::Size& view_size); private: +#if defined(OS_MACOSX) + // Creates a CGLayer associated with its owner view's window's graphics + // context, sized properly for the backing store. Returns NULL if the owner + // is not in a window with a CGContext. cg_layer_ is assigned this method's + // result. + CGLayerRef CreateCGLayer(); + + // Creates a CGBitmapContext sized properly for the backing store. The + // owner view need not be in a window. cg_bitmap_ is assigned this method's + // result. + CGContextRef CreateCGBitmapContext(); +#endif + // The owner of this backing store. RenderWidgetHost* render_widget_host_; diff --git a/chrome/browser/renderer_host/backing_store_mac.mm b/chrome/browser/renderer_host/backing_store_mac.mm index 567d8b9..7aefe99 100644 --- a/chrome/browser/renderer_host/backing_store_mac.mm +++ b/chrome/browser/renderer_host/backing_store_mac.mm @@ -24,23 +24,11 @@ BackingStore::BackingStore(RenderWidgetHost* widget, const gfx::Size& size) : render_widget_host_(widget), - size_(size), - cg_layer_(NULL) { - // We want our CGLayer to be optimized for drawing into our containing - // window, so extract a CGContext corresponding to that window that we can - // pass to CGLayerCreateWithContext. - NSWindow* containing_window = [widget->view()->GetNativeView() window]; - if (!containing_window) { - // If we are not in a containing window yet, create a CGBitmapContext - // to use as a stand-in for the layer. - cg_bitmap_.reset(CGBitmapContextCreate(NULL, size.width(), size.height(), - 8, size.width() * 4, mac_util::GetSystemColorSpace(), - kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host)); - } else { - CGContextRef context = static_cast<CGContextRef>( - [[containing_window graphicsContext] graphicsPort]); - CGLayerRef layer = CGLayerCreateWithContext(context, size.ToCGSize(), NULL); - cg_layer_.reset(layer); + size_(size) { + cg_layer_.reset(CreateCGLayer()); + if (!cg_layer_) { + // The view isn't in a window yet. Use a CGBitmapContext for now. + cg_bitmap_.reset(CreateCGBitmapContext()); } } @@ -68,19 +56,13 @@ void BackingStore::PaintRect(base::ProcessHandle process, data_provider, NULL, false, kCGRenderingIntentDefault)); if (!cg_layer()) { - // we don't have a CGLayer yet, so see if we can create one. - NSWindow* containing_window = - [render_widget_host()->view()->GetNativeView() window]; - if (containing_window) { - CGContextRef context = static_cast<CGContextRef>( - [[containing_window graphicsContext] graphicsPort]); - CGLayerRef layer = - CGLayerCreateWithContext(context, size().ToCGSize(), NULL); - cg_layer_.reset(layer); + // The view may have moved to a window. Try to get a CGLayer. + cg_layer_.reset(CreateCGLayer()); + if (cg_layer()) { // now that we have a layer, copy the cached image into it scoped_cftyperef<CGImageRef> bitmap_image( CGBitmapContextCreateImage(cg_bitmap_)); - CGContextDrawImage(CGLayerGetContext(layer), + CGContextDrawImage(CGLayerGetContext(cg_layer()), CGRectMake(0, 0, size().width(), size().height()), bitmap_image); // Discard the cache bitmap, since we no longer need it. @@ -130,9 +112,11 @@ void BackingStore::ScrollRect(base::ProcessHandle process, if ((dx || dy) && abs(dx) < size_.width() && abs(dy) < size_.height()) { if (cg_layer()) { - CGContextRef context = CGLayerGetContext(cg_layer()); - scoped_cftyperef<CGLayerRef> new_layer( - CGLayerCreateWithContext(context, size_.ToCGSize(), NULL)); + scoped_cftyperef<CGLayerRef> new_layer(CreateCGLayer()); + + // If the current view is in a window, the replacement must be too. + DCHECK(new_layer); + CGContextRef layer = CGLayerGetContext(new_layer); CGContextDrawLayerAtPoint(layer, CGPointMake(0, 0), cg_layer()); CGContextSaveGState(layer); @@ -145,10 +129,7 @@ void BackingStore::ScrollRect(base::ProcessHandle process, cg_layer_.swap(new_layer); } else { // We don't have a layer, so scroll the contents of the CGBitmapContext. - scoped_cftyperef<CGContextRef> new_bitmap( - CGBitmapContextCreate(NULL, size_.width(), size_.height(), 8, - size_.width() * 4, mac_util::GetSystemColorSpace(), - kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host)); + scoped_cftyperef<CGContextRef> new_bitmap(CreateCGBitmapContext()); scoped_cftyperef<CGImageRef> bitmap_image( CGBitmapContextCreateImage(cg_bitmap_)); CGContextDrawImage(new_bitmap, @@ -171,3 +152,43 @@ void BackingStore::ScrollRect(base::ProcessHandle process, PaintRect(process, bitmap, bitmap_rect); return; } + +CGLayerRef BackingStore::CreateCGLayer() { + // The CGLayer should be optimized for drawing into the containing window, + // so extract a CGContext corresponding to the window to be passed to + // CGLayerCreateWithContext. + NSWindow* window = [render_widget_host()->view()->GetNativeView() window]; + if ([window windowNumber] <= 0) { + // This catches a nil |window|, as well as windows that exist but that + // aren't yet connected to WindowServer. + return NULL; + } + + NSGraphicsContext* ns_context = [window graphicsContext]; + DCHECK(ns_context); + + CGContextRef cg_context = static_cast<CGContextRef>( + [ns_context graphicsPort]); + DCHECK(cg_context); + + CGLayerRef layer = CGLayerCreateWithContext(cg_context, + size_.ToCGSize(), + NULL); + DCHECK(layer); + + return layer; +} + +CGContextRef BackingStore::CreateCGBitmapContext() { + // A CGBitmapContext serves as a stand-in for the layer before the view is + // in a containing window. + CGContextRef context = CGBitmapContextCreate(NULL, + size_.width(), size_.height(), + 8, size_.width() * 4, + mac_util::GetSystemColorSpace(), + kCGImageAlphaPremultipliedFirst | + kCGBitmapByteOrder32Host); + DCHECK(context); + + return context; +} |