| Index: chrome/browser/renderer_host/backing_store_mac.mm
|
| ===================================================================
|
| --- chrome/browser/renderer_host/backing_store_mac.mm (revision 24883)
|
| +++ chrome/browser/renderer_host/backing_store_mac.mm (working copy)
|
| @@ -29,11 +29,20 @@
|
| // 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) // possible in unit tests
|
| - return;
|
| - CGContextRef context = static_cast<CGContextRef>([[containing_window graphicsContext] graphicsPort]);
|
| - CGLayerRef layer = CGLayerCreateWithContext(context, size.ToCGSize(), NULL);
|
| - cg_layer_.reset(layer);
|
| + if (!containing_window) {
|
| + // If we are not in a containing window yet, create a CGBitmapContext
|
| + // to use as a stand-in for the layer.
|
| + scoped_cftyperef<CGColorSpaceRef>
|
| + color_space(CGColorSpaceCreateDeviceRGB());
|
| + cg_bitmap_.reset(CGBitmapContextCreate(NULL, size.width(), size.height(),
|
| + 8, size.width() * 8, color_space,
|
| + kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host));
|
| + } else {
|
| + CGContextRef context = static_cast<CGContextRef>(
|
| + [[containing_window graphicsContext] graphicsPort]);
|
| + CGLayerRef layer = CGLayerCreateWithContext(context, size.ToCGSize(), NULL);
|
| + cg_layer_.reset(layer);
|
| + }
|
| }
|
|
|
| BackingStore::~BackingStore() {
|
| @@ -48,24 +57,51 @@
|
| void BackingStore::PaintRect(base::ProcessHandle process,
|
| TransportDIB* bitmap,
|
| const gfx::Rect& bitmap_rect) {
|
| - if (!cg_layer()) return;
|
| -
|
| scoped_cftyperef<CGColorSpaceRef> color_space(CGColorSpaceCreateDeviceRGB());
|
| scoped_cftyperef<CGDataProviderRef> data_provider(
|
| CGDataProviderCreateWithData(NULL, bitmap->memory(),
|
| - bitmap_rect.width() * bitmap_rect.height() * 4, NULL));
|
| - scoped_cftyperef<CGImageRef> image(CGImageCreate(bitmap_rect.width(),
|
| - bitmap_rect.height(), 8, 32, 4 * bitmap_rect.width(), color_space,
|
| - kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, data_provider,
|
| - NULL, false, kCGRenderingIntentDefault));
|
| + bitmap_rect.width() * bitmap_rect.height() * 4, NULL));
|
| + scoped_cftyperef<CGImageRef> image(
|
| + CGImageCreate(bitmap_rect.width(), bitmap_rect.height(), 8, 32,
|
| + 4 * bitmap_rect.width(), color_space,
|
| + kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host,
|
| + data_provider, NULL, false, kCGRenderingIntentDefault));
|
|
|
| - // The CGLayer's origin is in the lower left, but flipping the CTM would
|
| - // cause the image to get drawn upside down. So we move the rectangle
|
| - // to the right position before drawing the image.
|
| - CGContextRef layer = CGLayerGetContext(cg_layer());
|
| - gfx::Rect paint_rect = bitmap_rect;
|
| - paint_rect.set_y(size_.height() - bitmap_rect.bottom());
|
| - CGContextDrawImage(layer, paint_rect.ToCGRect(), image);
|
| + 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);
|
| + // now that we have a layer, copy the cached image into it
|
| + scoped_cftyperef<CGImageRef> bitmap_image(
|
| + CGBitmapContextCreateImage(cg_bitmap_));
|
| + CGContextDrawImage(CGLayerGetContext(layer),
|
| + CGRectMake(0, 0, size().width(), size().height()),
|
| + bitmap_image);
|
| + // Discard the cache bitmap, since we no longer need it.
|
| + cg_bitmap_.reset(NULL);
|
| + }
|
| + }
|
| +
|
| + if (cg_layer()) {
|
| + // The CGLayer's origin is in the lower left, but flipping the CTM would
|
| + // cause the image to get drawn upside down. So we move the rectangle
|
| + // to the right position before drawing the image.
|
| + CGContextRef layer = CGLayerGetContext(cg_layer());
|
| + gfx::Rect paint_rect = bitmap_rect;
|
| + paint_rect.set_y(size_.height() - bitmap_rect.bottom());
|
| + CGContextDrawImage(layer, paint_rect.ToCGRect(), image);
|
| + } else {
|
| + // The layer hasn't been created yet, so draw into the cache bitmap.
|
| + gfx::Rect paint_rect = bitmap_rect;
|
| + paint_rect.set_y(size_.height() - bitmap_rect.bottom());
|
| + CGContextDrawImage(cg_bitmap_, paint_rect.ToCGRect(), image);
|
| + }
|
| }
|
|
|
| // Scroll the contents of our CGLayer
|
| @@ -93,21 +129,47 @@
|
|
|
| if ((dx && abs(dx) < layer_size.width) ||
|
| (dy && abs(dy) < layer_size.height)) {
|
| - //
|
| - scoped_cftyperef<CGLayerRef> new_layer(CGLayerCreateWithContext(
|
| - CGLayerGetContext(cg_layer()), layer_size, NULL));
|
| - CGContextRef layer = CGLayerGetContext(new_layer);
|
| - CGContextDrawLayerAtPoint(layer, CGPointMake(0, 0), cg_layer());
|
| - CGContextSaveGState(layer);
|
| - CGContextClipToRect(layer, CGRectMake(clip_rect.x(),
|
| - size_.height() - clip_rect.bottom(),
|
| - clip_rect.width(),
|
| - clip_rect.height()));
|
| - CGContextDrawLayerAtPoint(layer, CGPointMake(dx, -dy), cg_layer());
|
| - CGContextRestoreGState(layer);
|
| - cg_layer_.swap(new_layer);
|
| + if (cg_layer()) {
|
| + CGContextRef context = CGLayerGetContext(cg_layer());
|
| + scoped_cftyperef<CGLayerRef> new_layer(
|
| + CGLayerCreateWithContext(context, layer_size, NULL));
|
| + CGContextRef layer = CGLayerGetContext(new_layer);
|
| + CGContextDrawLayerAtPoint(layer, CGPointMake(0, 0), cg_layer());
|
| + CGContextSaveGState(layer);
|
| + CGContextClipToRect(layer, CGRectMake(clip_rect.x(),
|
| + size_.height() - clip_rect.bottom(),
|
| + clip_rect.width(),
|
| + clip_rect.height()));
|
| + CGContextDrawLayerAtPoint(layer, CGPointMake(dx, -dy), cg_layer());
|
| + CGContextRestoreGState(layer);
|
| + cg_layer_.swap(new_layer);
|
| + } else {
|
| + // We don't have a layer, so scroll the contents of the CGBitmapContext.
|
| + scoped_cftyperef<CGColorSpaceRef>
|
| + color_space(CGColorSpaceCreateDeviceRGB());
|
| + scoped_cftyperef<CGContextRef> new_bitmap(
|
| + CGBitmapContextCreate(NULL, size_.width(), size_.height(), 8,
|
| + size_.width() * 8, color_space,
|
| + kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host));
|
| + scoped_cftyperef<CGImageRef> bitmap_image(
|
| + CGBitmapContextCreateImage(cg_bitmap_));
|
| + CGContextDrawImage(new_bitmap,
|
| + CGRectMake(0, 0, size_.width(), size_.height()),
|
| + bitmap_image);
|
| + CGContextSaveGState(new_bitmap);
|
| + CGContextClipToRect(new_bitmap,
|
| + CGRectMake(clip_rect.x(),
|
| + size_.height() - clip_rect.bottom(),
|
| + clip_rect.width(),
|
| + clip_rect.height()));
|
| + CGContextDrawImage(new_bitmap,
|
| + CGRectMake(dx, -dy, size_.width(), size_.height()),
|
| + bitmap_image);
|
| + CGContextRestoreGState(new_bitmap);
|
| + cg_bitmap_.swap(new_bitmap);
|
| + }
|
| }
|
| - // Now paint the new bitmap data into the CGLayer
|
| + // Now paint the new bitmap data
|
| PaintRect(process, bitmap, bitmap_rect);
|
| return;
|
| }
|
|
|