summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authormark@chromium.org <mark@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-10 19:02:02 +0000
committermark@chromium.org <mark@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-10 19:02:02 +0000
commitcccb18d27e0243f20539d4450c0d21ee2ab2a200 (patch)
tree088cfdec74d426be2806236038bac3add49eed3b /chrome
parent0f88d3274bd3c093744a2de1c5d8e9f5f2643a77 (diff)
downloadchromium_src-cccb18d27e0243f20539d4450c0d21ee2ab2a200.zip
chromium_src-cccb18d27e0243f20539d4450c0d21ee2ab2a200.tar.gz
chromium_src-cccb18d27e0243f20539d4450c0d21ee2ab2a200.tar.bz2
Back out r31572, reinstating r31563:
Always create BackingStore CGLayers using the owner view's window's context as a reference. Reorganize CGLayer and CGBitmapContext creation into common functions. BUG=26989 TEST=Still paints? Good. Review URL: http://codereview.chromium.org/384011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@31578 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/renderer_host/backing_store.h13
-rw-r--r--chrome/browser/renderer_host/backing_store_mac.mm89
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;
+}