summaryrefslogtreecommitdiffstats
path: root/chromium/content/browser/renderer_host/backing_store_mac.mm
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/content/browser/renderer_host/backing_store_mac.mm')
-rw-r--r--chromium/content/browser/renderer_host/backing_store_mac.mm297
1 files changed, 0 insertions, 297 deletions
diff --git a/chromium/content/browser/renderer_host/backing_store_mac.mm b/chromium/content/browser/renderer_host/backing_store_mac.mm
deleted file mode 100644
index 8b3fda9840d..00000000000
--- a/chromium/content/browser/renderer_host/backing_store_mac.mm
+++ /dev/null
@@ -1,297 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#import <Cocoa/Cocoa.h>
-
-#include "content/browser/renderer_host/backing_store_mac.h"
-
-#include <cmath>
-
-#include "base/logging.h"
-#include "base/mac/mac_util.h"
-#include "base/mac/scoped_cftyperef.h"
-#include "content/browser/renderer_host/render_process_host_impl.h"
-#include "content/browser/renderer_host/render_widget_host_impl.h"
-#include "content/public/browser/render_widget_host_view.h"
-#include "skia/ext/platform_canvas.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "third_party/skia/include/core/SkCanvas.h"
-#include "ui/gfx/rect.h"
-#include "ui/gfx/rect_conversions.h"
-#include "ui/gfx/size_conversions.h"
-#include "ui/gfx/scoped_cg_context_save_gstate_mac.h"
-#include "ui/surface/transport_dib.h"
-
-namespace content {
-
-// Mac Backing Stores:
-//
-// Since backing stores are only ever written to or drawn into windows, we keep
-// our backing store in a CGLayer that can get cached in GPU memory. This
-// allows acclerated drawing into the layer and lets scrolling and such happen
-// all or mostly on the GPU, which is good for performance.
-
-BackingStoreMac::BackingStoreMac(RenderWidgetHost* widget,
- const gfx::Size& size,
- float device_scale_factor)
- : BackingStore(widget, size), device_scale_factor_(device_scale_factor) {
- cg_layer_.reset(CreateCGLayer());
- if (!cg_layer_) {
- // The view isn't in a window yet. Use a CGBitmapContext for now.
- cg_bitmap_.reset(CreateCGBitmapContext());
- CGContextScaleCTM(cg_bitmap_, device_scale_factor_, device_scale_factor_);
- }
-}
-
-BackingStoreMac::~BackingStoreMac() {
-}
-
-void BackingStoreMac::ScaleFactorChanged(float device_scale_factor) {
- if (device_scale_factor == device_scale_factor_)
- return;
-
- device_scale_factor_ = device_scale_factor;
-
- base::ScopedCFTypeRef<CGLayerRef> new_layer(CreateCGLayer());
- // If we have a layer, copy the old contents. A pixelated flash is better
- // than a white flash.
- if (new_layer && cg_layer_) {
- CGContextRef layer = CGLayerGetContext(new_layer);
- CGContextDrawLayerAtPoint(layer, CGPointMake(0, 0), cg_layer_);
- }
-
- cg_layer_.swap(new_layer);
- if (!cg_layer_) {
- // The view isn't in a window yet. Use a CGBitmapContext for now.
- cg_bitmap_.reset(CreateCGBitmapContext());
- CGContextScaleCTM(cg_bitmap_, device_scale_factor_, device_scale_factor_);
- }
-}
-
-size_t BackingStoreMac::MemorySize() {
- return gfx::ToFlooredSize(
- gfx::ScaleSize(size(), device_scale_factor_)).GetArea() * 4;
-}
-
-void BackingStoreMac::PaintToBackingStore(
- RenderProcessHost* process,
- TransportDIB::Id bitmap,
- const gfx::Rect& bitmap_rect,
- const std::vector<gfx::Rect>& copy_rects,
- float scale_factor,
- const base::Closure& completion_callback,
- bool* scheduled_completion_callback) {
- *scheduled_completion_callback = false;
- DCHECK_NE(static_cast<bool>(cg_layer()), static_cast<bool>(cg_bitmap()));
-
- TransportDIB* dib = process->GetTransportDIB(bitmap);
- if (!dib)
- return;
-
- gfx::Size pixel_size = gfx::ToFlooredSize(
- gfx::ScaleSize(size(), device_scale_factor_));
- gfx::Rect pixel_bitmap_rect = ToFlooredRectDeprecated(
- gfx::ScaleRect(bitmap_rect, scale_factor));
-
- size_t bitmap_byte_count =
- pixel_bitmap_rect.width() * pixel_bitmap_rect.height() * 4;
- DCHECK_GE(dib->size(), bitmap_byte_count);
-
- base::ScopedCFTypeRef<CGDataProviderRef> data_provider(
- CGDataProviderCreateWithData(
- NULL, dib->memory(), bitmap_byte_count, NULL));
-
- base::ScopedCFTypeRef<CGImageRef> bitmap_image(
- CGImageCreate(pixel_bitmap_rect.width(),
- pixel_bitmap_rect.height(),
- 8,
- 32,
- 4 * pixel_bitmap_rect.width(),
- base::mac::GetSystemColorSpace(),
- kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host,
- data_provider,
- NULL,
- false,
- kCGRenderingIntentDefault));
-
- for (size_t i = 0; i < copy_rects.size(); i++) {
- const gfx::Rect& copy_rect = copy_rects[i];
- gfx::Rect pixel_copy_rect = ToFlooredRectDeprecated(
- gfx::ScaleRect(copy_rect, scale_factor));
-
- // Only the subpixels given by copy_rect have pixels to copy.
- base::ScopedCFTypeRef<CGImageRef> image(CGImageCreateWithImageInRect(
- bitmap_image,
- CGRectMake(pixel_copy_rect.x() - pixel_bitmap_rect.x(),
- pixel_copy_rect.y() - pixel_bitmap_rect.y(),
- pixel_copy_rect.width(),
- pixel_copy_rect.height())));
-
- if (!cg_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.
- base::ScopedCFTypeRef<CGImageRef> bitmap_image(
- CGBitmapContextCreateImage(cg_bitmap_));
- CGContextDrawImage(CGLayerGetContext(cg_layer()),
- CGRectMake(0, 0, size().width(), size().height()),
- bitmap_image);
- // Discard the cache bitmap, since we no longer need it.
- cg_bitmap_.reset(NULL);
- }
- }
-
- DCHECK_NE(static_cast<bool>(cg_layer()), static_cast<bool>(cg_bitmap()));
-
- 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 = copy_rect;
- paint_rect.set_y(size().height() - copy_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 = copy_rect;
- paint_rect.set_y(size().height() - copy_rect.bottom());
- CGContextDrawImage(cg_bitmap_, paint_rect.ToCGRect(), image);
- }
- }
-}
-
-bool BackingStoreMac::CopyFromBackingStore(const gfx::Rect& rect,
- skia::PlatformBitmap* output) {
- // TODO(thakis): Make sure this works with HiDPI backing stores.
- if (!output->Allocate(rect.width(), rect.height(), true))
- return false;
-
- CGContextRef temp_context = output->GetSurface();
- gfx::ScopedCGContextSaveGState save_gstate(temp_context);
- CGContextTranslateCTM(temp_context, 0.0, size().height());
- CGContextScaleCTM(temp_context, 1.0, -1.0);
- if (cg_layer()) {
- CGContextDrawLayerAtPoint(temp_context, CGPointMake(-rect.x(), -rect.y()),
- cg_layer());
- } else {
- base::ScopedCFTypeRef<CGImageRef> bitmap_image(
- CGBitmapContextCreateImage(cg_bitmap_));
- CGContextDrawImage(
- temp_context,
- CGRectMake(-rect.x(), -rect.y(), rect.width(), rect.height()),
- bitmap_image);
- }
-
- return true;
-}
-
-// Scroll the contents of our CGLayer
-void BackingStoreMac::ScrollBackingStore(const gfx::Vector2d& delta,
- const gfx::Rect& clip_rect,
- const gfx::Size& view_size) {
- DCHECK_NE(static_cast<bool>(cg_layer()), static_cast<bool>(cg_bitmap()));
-
- // "Scroll" the contents of the layer by creating a new CGLayer,
- // copying the contents of the old one into the new one offset by the scroll
- // amount, swapping in the new CGLayer, and then painting in the new data.
- //
- // The Windows code always sets the whole backing store as the source of the
- // scroll. Thus, we only have to worry about pixels which will end up inside
- // the clipping rectangle. (Note that the clipping rectangle is not
- // translated by the scroll.)
-
- // We assume |clip_rect| is contained within the backing store.
- DCHECK(clip_rect.bottom() <= size().height());
- DCHECK(clip_rect.right() <= size().width());
-
- if ((delta.x() || delta.y()) &&
- abs(delta.x()) < size().width() && abs(delta.y()) < size().height()) {
- if (cg_layer()) {
- CGContextRef layer = CGLayerGetContext(cg_layer());
- gfx::ScopedCGContextSaveGState save_gstate(layer);
- CGContextClipToRect(layer,
- CGRectMake(clip_rect.x(),
- size().height() - clip_rect.bottom(),
- clip_rect.width(),
- clip_rect.height()));
- CGContextDrawLayerAtPoint(layer,
- CGPointMake(delta.x(), -delta.y()), cg_layer());
- } else {
- // We don't have a layer, so scroll the contents of the CGBitmapContext.
- base::ScopedCFTypeRef<CGImageRef> bitmap_image(
- CGBitmapContextCreateImage(cg_bitmap_));
- gfx::ScopedCGContextSaveGState save_gstate(cg_bitmap_);
- CGContextClipToRect(cg_bitmap_,
- CGRectMake(clip_rect.x(),
- size().height() - clip_rect.bottom(),
- clip_rect.width(),
- clip_rect.height()));
- CGContextDrawImage(cg_bitmap_,
- CGRectMake(delta.x(), -delta.y(),
- size().width(), size().height()),
- bitmap_image);
- }
- }
-}
-
-void BackingStoreMac::CopyFromBackingStoreToCGContext(const CGRect& dest_rect,
- CGContextRef context) {
- gfx::ScopedCGContextSaveGState save_gstate(context);
- CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
- if (cg_layer_) {
- CGContextDrawLayerInRect(context, dest_rect, cg_layer_);
- } else {
- base::ScopedCFTypeRef<CGImageRef> image(
- CGBitmapContextCreateImage(cg_bitmap_));
- CGContextDrawImage(context, dest_rect, image);
- }
-}
-
-CGLayerRef BackingStoreMac::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()->GetView()->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);
-
- // Note: This takes the backingScaleFactor of cg_context into account. The
- // bitmap backing |layer| will be size() * 2 in HiDPI mode automatically.
- CGLayerRef layer = CGLayerCreateWithContext(cg_context,
- size().ToCGSize(),
- NULL);
- DCHECK(layer);
-
- return layer;
-}
-
-CGContextRef BackingStoreMac::CreateCGBitmapContext() {
- gfx::Size pixel_size = gfx::ToFlooredSize(
- gfx::ScaleSize(size(), device_scale_factor_));
- // A CGBitmapContext serves as a stand-in for the layer before the view is
- // in a containing window.
- CGContextRef context = CGBitmapContextCreate(NULL,
- pixel_size.width(),
- pixel_size.height(),
- 8, pixel_size.width() * 4,
- base::mac::GetSystemColorSpace(),
- kCGImageAlphaPremultipliedFirst |
- kCGBitmapByteOrder32Host);
- DCHECK(context);
-
- return context;
-}
-
-} // namespace content