| Index: content/browser/renderer_host/render_widget_host_view_mac.mm
 | 
| diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm
 | 
| index 5dd40b00829d2884ec34bbf7c846392110ed59c1..ab3cf101dd0eb34079d41b935a3488ef16b9f8ee 100644
 | 
| --- a/content/browser/renderer_host/render_widget_host_view_mac.mm
 | 
| +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
 | 
| @@ -8,11 +8,13 @@
 | 
|  
 | 
|  #include "base/bind.h"
 | 
|  #include "base/bind_helpers.h"
 | 
| +#include "base/command_line.h"
 | 
|  #include "base/debug/crash_logging.h"
 | 
|  #include "base/debug/trace_event.h"
 | 
|  #include "base/logging.h"
 | 
|  #include "base/mac/mac_util.h"
 | 
|  #include "base/mac/scoped_cftyperef.h"
 | 
| +#include "base/mac/sdk_forward_declarations.h"
 | 
|  #import "base/memory/scoped_nsobject.h"
 | 
|  #include "base/message_loop.h"
 | 
|  #include "base/metrics/histogram.h"
 | 
| @@ -25,6 +27,8 @@
 | 
|  #include "content/browser/accessibility/browser_accessibility_manager_mac.h"
 | 
|  #include "content/browser/renderer_host/backing_store_mac.h"
 | 
|  #include "content/browser/renderer_host/backing_store_manager.h"
 | 
| +#include "content/browser/renderer_host/compositing_iosurface_context_mac.h"
 | 
| +#include "content/browser/renderer_host/compositing_iosurface_layer_mac.h"
 | 
|  #include "content/browser/renderer_host/compositing_iosurface_mac.h"
 | 
|  #include "content/browser/renderer_host/render_view_host_impl.h"
 | 
|  #import "content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.h"
 | 
| @@ -38,12 +42,14 @@
 | 
|  #include "content/public/browser/browser_thread.h"
 | 
|  #include "content/public/browser/native_web_keyboard_event.h"
 | 
|  #import "content/public/browser/render_widget_host_view_mac_delegate.h"
 | 
| +#include "content/public/common/content_switches.h"
 | 
|  #include "skia/ext/platform_canvas.h"
 | 
|  #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
 | 
|  #include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h"
 | 
|  #include "third_party/WebKit/Source/WebKit/chromium/public/mac/WebInputEventFactory.h"
 | 
|  #include "third_party/WebKit/Source/WebKit/chromium/public/mac/WebScreenInfoFactory.h"
 | 
|  #import "third_party/mozilla/ComplexTextInputPanel.h"
 | 
| +#include "ui/base/cocoa/animation_utils.h"
 | 
|  #import "ui/base/cocoa/fullscreen_window_manager.h"
 | 
|  #import "ui/base/cocoa/underlay_opengl_hosting_window.h"
 | 
|  #include "ui/base/keycodes/keyboard_codes.h"
 | 
| @@ -80,15 +86,6 @@ using WebKit::WebMouseWheelEvent;
 | 
|  // Declare things that are part of the 10.7 SDK.
 | 
|  #if !defined(MAC_OS_X_VERSION_10_7) || \
 | 
|      MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
 | 
| -enum {
 | 
| -  NSEventPhaseNone        = 0, // event not associated with a phase.
 | 
| -  NSEventPhaseBegan       = 0x1 << 0,
 | 
| -  NSEventPhaseStationary  = 0x1 << 1,
 | 
| -  NSEventPhaseChanged     = 0x1 << 2,
 | 
| -  NSEventPhaseEnded       = 0x1 << 3,
 | 
| -  NSEventPhaseCancelled   = 0x1 << 4,
 | 
| -};
 | 
| -typedef NSUInteger NSEventPhase;
 | 
|  
 | 
|  @interface NSEvent (LionAPI)
 | 
|  - (NSEventPhase)phase;
 | 
| @@ -115,7 +112,6 @@ static NSString* const NSBackingPropertyOldScaleFactorKey =
 | 
|  
 | 
|  #endif  // 10.7
 | 
|  
 | 
| -
 | 
|  static inline int ToWebKitModifiers(NSUInteger flags) {
 | 
|    int modifiers = 0;
 | 
|    if (flags & NSControlKeyMask) modifiers |= WebInputEvent::ControlKey;
 | 
| @@ -144,6 +140,10 @@ static float ScaleFactor(NSView* view) {
 | 
|  - (void)keyEvent:(NSEvent*)theEvent wasKeyEquivalent:(BOOL)equiv;
 | 
|  - (void)windowDidChangeBackingProperties:(NSNotification*)notification;
 | 
|  - (void)windowChangedGlobalFrame:(NSNotification*)notification;
 | 
| +- (void)drawBackingStore:(BackingStoreMac*)backingStore
 | 
| +               dirtyRect:(CGRect)dirtyRect
 | 
| +               inContext:(CGContextRef)context;
 | 
| +- (void)updateSoftwareLayerScaleFactor;
 | 
|  - (void)checkForPluginImeCancellation;
 | 
|  - (void)updateTabBackingStoreScaleFactor;
 | 
|  - (NSRect)firstViewRectForCharacterRange:(NSRange)theRange
 | 
| @@ -366,6 +366,7 @@ RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget)
 | 
|        text_input_type_(ui::TEXT_INPUT_TYPE_NONE),
 | 
|        can_compose_inline_(true),
 | 
|        allow_overlapping_views_(false),
 | 
| +      use_core_animation_(false),
 | 
|        is_loading_(false),
 | 
|        is_hidden_(false),
 | 
|        weak_factory_(this),
 | 
| @@ -375,12 +376,21 @@ RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget)
 | 
|    // |GetNativeView()| into the view hierarchy right after calling us.
 | 
|    cocoa_view_ = [[[RenderWidgetHostViewCocoa alloc]
 | 
|                    initWithRenderWidgetHostViewMac:this] autorelease];
 | 
| +  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseCoreAnimation))
 | 
| +    EnableCoreAnimation();
 | 
|    render_widget_host_->SetView(this);
 | 
|  }
 | 
|  
 | 
|  RenderWidgetHostViewMac::~RenderWidgetHostViewMac() {
 | 
|    AckPendingSwapBuffers();
 | 
|    UnlockMouse();
 | 
| +
 | 
| +  // Make sure that the layer doesn't reach into the now-invalid object.
 | 
| +  compositing_iosurface_.reset();
 | 
| +  if (compositing_iosurface_layer_)
 | 
| +    [compositing_iosurface_layer_ disableCompositing];
 | 
| +  compositing_iosurface_layer_.reset();
 | 
| +
 | 
|    // We are owned by RenderWidgetHostViewCocoa, so if we go away before the
 | 
|    // RenderWidgetHost does we need to tell it not to hold a stale pointer to
 | 
|    // us.
 | 
| @@ -394,6 +404,8 @@ void RenderWidgetHostViewMac::SetDelegate(
 | 
|  }
 | 
|  
 | 
|  void RenderWidgetHostViewMac::SetAllowOverlappingViews(bool overlapping) {
 | 
| +  if (use_core_animation_)
 | 
| +    return;
 | 
|    if (allow_overlapping_views_ == overlapping)
 | 
|      return;
 | 
|    allow_overlapping_views_ = overlapping;
 | 
| @@ -404,6 +416,21 @@ void RenderWidgetHostViewMac::SetAllowOverlappingViews(bool overlapping) {
 | 
|  ///////////////////////////////////////////////////////////////////////////////
 | 
|  // RenderWidgetHostViewMac, RenderWidgetHostView implementation:
 | 
|  
 | 
| +void RenderWidgetHostViewMac::EnableCoreAnimation() {
 | 
| +  if (use_core_animation_)
 | 
| +    return;
 | 
| +  use_core_animation_ = true;
 | 
| +
 | 
| +  software_layer_.reset([[CALayer alloc] init]);
 | 
| +  [software_layer_ setDelegate:cocoa_view_];
 | 
| +  [software_layer_ setAutoresizingMask:kCALayerWidthSizable |
 | 
| +                                       kCALayerHeightSizable];
 | 
| +  [software_layer_ setContentsGravity:kCAGravityTopLeft];
 | 
| +  [cocoa_view_ updateSoftwareLayerScaleFactor];
 | 
| +  [cocoa_view_ setLayer:software_layer_];
 | 
| +  [cocoa_view_ setWantsLayer:YES];
 | 
| +}
 | 
| +
 | 
|  bool RenderWidgetHostViewMac::OnMessageReceived(const IPC::Message& message) {
 | 
|    bool handled = true;
 | 
|    IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewMac, message)
 | 
| @@ -516,6 +543,10 @@ int RenderWidgetHostViewMac::window_number() const {
 | 
|    return [window windowNumber];
 | 
|  }
 | 
|  
 | 
| +float RenderWidgetHostViewMac::scale_factor() const {
 | 
| +  return ScaleFactor(cocoa_view_);
 | 
| +}
 | 
| +
 | 
|  RenderWidgetHost* RenderWidgetHostViewMac::GetRenderWidgetHost() const {
 | 
|    return render_widget_host_;
 | 
|  }
 | 
| @@ -530,7 +561,11 @@ void RenderWidgetHostViewMac::WasShown() {
 | 
|    render_widget_host_->WasShown();
 | 
|  
 | 
|    // We're messing with the window, so do this to ensure no flashes.
 | 
| -  [[cocoa_view_ window] disableScreenUpdatesUntilFlush];
 | 
| +  if (!use_core_animation_)
 | 
| +    [[cocoa_view_ window] disableScreenUpdatesUntilFlush];
 | 
| +
 | 
| +  if (compositing_iosurface_layer_)
 | 
| +    [compositing_iosurface_layer_ setNeedsDisplay];
 | 
|  }
 | 
|  
 | 
|  void RenderWidgetHostViewMac::WasHidden() {
 | 
| @@ -555,7 +590,8 @@ void RenderWidgetHostViewMac::WasHidden() {
 | 
|    // the NSView and its corresponding OpenGL context.
 | 
|    // disableScreenUpdatesUntilFlush prevents the transparent flash by avoiding
 | 
|    // screen updates until the next tab draws.
 | 
| -  [[cocoa_view_ window] disableScreenUpdatesUntilFlush];
 | 
| +  if (!use_core_animation_)
 | 
| +    [[cocoa_view_ window] disableScreenUpdatesUntilFlush];
 | 
|  
 | 
|    web_contents_switch_paint_time_ = base::TimeTicks();
 | 
|  }
 | 
| @@ -647,7 +683,7 @@ bool RenderWidgetHostViewMac::HasFocus() const {
 | 
|  
 | 
|  bool RenderWidgetHostViewMac::IsSurfaceAvailableForCopy() const {
 | 
|    return !!render_widget_host_->GetBackingStore(false) ||
 | 
| -      (compositing_iosurface_.get() && compositing_iosurface_->HasIOSurface());
 | 
| +      (compositing_iosurface_ && compositing_iosurface_->HasIOSurface());
 | 
|  }
 | 
|  
 | 
|  void RenderWidgetHostViewMac::Show() {
 | 
| @@ -936,7 +972,7 @@ void RenderWidgetHostViewMac::CopyFromCompositingSurface(
 | 
|      const base::Callback<void(bool, const SkBitmap&)>& callback) {
 | 
|    base::ScopedClosureRunner scoped_callback_runner(
 | 
|        base::Bind(callback, false, SkBitmap()));
 | 
| -  if (!compositing_iosurface_.get() ||
 | 
| +  if (!compositing_iosurface_ ||
 | 
|        !compositing_iosurface_->HasIOSurface())
 | 
|      return;
 | 
|  
 | 
| @@ -957,7 +993,7 @@ void RenderWidgetHostViewMac::CopyFromCompositingSurfaceToVideoFrame(
 | 
|        const base::Callback<void(bool)>& callback) {
 | 
|    base::ScopedClosureRunner scoped_callback_runner(base::Bind(callback, false));
 | 
|    if (!render_widget_host_->is_accelerated_compositing_active() ||
 | 
| -      !compositing_iosurface_.get() ||
 | 
| +      !compositing_iosurface_ ||
 | 
|        !compositing_iosurface_->HasIOSurface())
 | 
|      return;
 | 
|  
 | 
| @@ -985,7 +1021,7 @@ void RenderWidgetHostViewMac::CopyFromCompositingSurfaceToVideoFrame(
 | 
|  bool RenderWidgetHostViewMac::CanCopyToVideoFrame() const {
 | 
|    return (!render_widget_host_->GetBackingStore(false) &&
 | 
|            render_widget_host_->is_accelerated_compositing_active() &&
 | 
| -          compositing_iosurface_.get() &&
 | 
| +          compositing_iosurface_ &&
 | 
|            compositing_iosurface_->HasIOSurface());
 | 
|  }
 | 
|  
 | 
| @@ -1050,7 +1086,7 @@ void RenderWidgetHostViewMac::PluginImeCompositionCompleted(
 | 
|  bool RenderWidgetHostViewMac::CompositorSwapBuffers(
 | 
|      uint64 surface_handle,
 | 
|      const gfx::Size& size,
 | 
| -    float scale_factor,
 | 
| +    float surface_scale_factor,
 | 
|      const ui::LatencyInfo& latency_info) {
 | 
|    if (is_hidden_)
 | 
|      return true;
 | 
| @@ -1059,14 +1095,14 @@ bool RenderWidgetHostViewMac::CompositorSwapBuffers(
 | 
|    if (window_number() <= 0) {
 | 
|      // There is no window to present so capturing during present won't work.
 | 
|      // We check if frame subscriber wants this frame and capture manually.
 | 
| -    if (compositing_iosurface_.get() && frame_subscriber_) {
 | 
| +    if (compositing_iosurface_ && frame_subscriber_) {
 | 
|        const base::Time present_time = base::Time::Now();
 | 
|        scoped_refptr<media::VideoFrame> frame;
 | 
|        RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback callback;
 | 
|        if (frame_subscriber_->ShouldCaptureFrame(present_time,
 | 
|                                                  &frame, &callback)) {
 | 
|          compositing_iosurface_->SetIOSurface(
 | 
| -            surface_handle, size, scale_factor, latency_info);
 | 
| +            surface_handle, size, surface_scale_factor, latency_info);
 | 
|          compositing_iosurface_->CopyToVideoFrame(
 | 
|              gfx::Rect(size), frame,
 | 
|              base::Bind(callback, present_time));
 | 
| @@ -1097,16 +1133,40 @@ bool RenderWidgetHostViewMac::CompositorSwapBuffers(
 | 
|  
 | 
|    bool should_post_notification = false;
 | 
|    if (!compositing_iosurface_) {
 | 
| -    compositing_iosurface_.reset(
 | 
| -        CompositingIOSurfaceMac::Create(window_number()));
 | 
| +    if (use_core_animation_) {
 | 
| +      if (!compositing_iosurface_layer_) {
 | 
| +        compositing_iosurface_layer_.reset([[CompositingIOSurfaceLayer alloc]
 | 
| +            initWithRenderWidgetHostViewMac:this]);
 | 
| +      }
 | 
| +      if (!compositing_iosurface_layer_) {
 | 
| +        LOG(WARNING) << "Failed to create CALayer for IOSurface";
 | 
| +        return true;
 | 
| +      }
 | 
| +      if (![compositing_iosurface_layer_ ensureContext]) {
 | 
| +        LOG(WARNING) << "Failed to create context for IOSurface";
 | 
| +        return true;
 | 
| +      }
 | 
| +      compositing_iosurface_.reset(CompositingIOSurfaceMac::Create(
 | 
| +          [compositing_iosurface_layer_ context]));
 | 
| +    } else {
 | 
| +      compositing_iosurface_.reset(
 | 
| +          CompositingIOSurfaceMac::Create(window_number()));
 | 
| +    }
 | 
|      should_post_notification = true;
 | 
|    }
 | 
|  
 | 
| -  if (!compositing_iosurface_)
 | 
| +  if (!compositing_iosurface_) {
 | 
| +    LOG(WARNING) << "Failed to create CompositingIOSurfaceMac";
 | 
|      return true;
 | 
| +  }
 | 
|  
 | 
|    compositing_iosurface_->SetIOSurface(
 | 
| -      surface_handle, size, scale_factor, latency_info);
 | 
| +      surface_handle, size, surface_scale_factor, latency_info);
 | 
| +
 | 
| +  // TODO(ccameron): If we've failed to allocate the GL texture for the
 | 
| +  // IOSurface, or basically anything else along the way, we'll just display
 | 
| +  // a white out, potentially forever. Instead, kick the renderer back to
 | 
| +  // software mode (like a context lost or a GPU process death).
 | 
|  
 | 
|    GotAcceleratedFrame();
 | 
|  
 | 
| @@ -1120,14 +1180,12 @@ bool RenderWidgetHostViewMac::CompositorSwapBuffers(
 | 
|    // No need to draw the surface if we are inside a drawRect. It will be done
 | 
|    // later.
 | 
|    if (!about_to_validate_and_paint_) {
 | 
| -    CompositingIOSurfaceMac::SurfaceOrder order = allow_overlapping_views_ ?
 | 
| -        CompositingIOSurfaceMac::SURFACE_ORDER_BELOW_WINDOW :
 | 
| -        CompositingIOSurfaceMac::SURFACE_ORDER_ABOVE_WINDOW;
 | 
| -    compositing_iosurface_->DrawIOSurface(cocoa_view_,
 | 
| -                                          ScaleFactor(cocoa_view_),
 | 
| -                                          window_number(),
 | 
| -                                          order,
 | 
| -                                          frame_subscriber_.get());
 | 
| +    if (use_core_animation_) {
 | 
| +      DCHECK(compositing_iosurface_layer_);
 | 
| +      [compositing_iosurface_layer_ setNeedsDisplay];
 | 
| +    } else {
 | 
| +      compositing_iosurface_->DrawIOSurface(this);
 | 
| +    }
 | 
|    }
 | 
|  
 | 
|    if (should_post_notification && [[cocoa_view_ delegate]
 | 
| @@ -1135,6 +1193,10 @@ bool RenderWidgetHostViewMac::CompositorSwapBuffers(
 | 
|      [[cocoa_view_ delegate] compositingIOSurfaceCreated];
 | 
|    }
 | 
|  
 | 
| +  // Don't ack the new frame until it is drawn.
 | 
| +  if (use_core_animation_)
 | 
| +    return false;
 | 
| +
 | 
|    return true;
 | 
|  }
 | 
|  
 | 
| @@ -1347,12 +1409,15 @@ void RenderWidgetHostViewMac::AcceleratedSurfaceSuspend() {
 | 
|  
 | 
|  void RenderWidgetHostViewMac::AcceleratedSurfaceRelease() {
 | 
|    compositing_iosurface_.reset();
 | 
| +  if (compositing_iosurface_layer_)
 | 
| +    [compositing_iosurface_layer_ disableCompositing];
 | 
| +  compositing_iosurface_layer_.reset();
 | 
|  }
 | 
|  
 | 
|  bool RenderWidgetHostViewMac::HasAcceleratedSurface(
 | 
|        const gfx::Size& desired_size) {
 | 
|    return last_frame_was_accelerated_ &&
 | 
| -         compositing_iosurface_.get() &&
 | 
| +         compositing_iosurface_ &&
 | 
|           compositing_iosurface_->HasIOSurface() &&
 | 
|           (desired_size.IsEmpty() ||
 | 
|            compositing_iosurface_->dip_io_surface_size() == desired_size);
 | 
| @@ -1450,12 +1515,19 @@ void RenderWidgetHostViewMac::ShutdownHost() {
 | 
|  }
 | 
|  
 | 
|  void RenderWidgetHostViewMac::GotAcceleratedFrame() {
 | 
| +  // Update the scale factor of the layer to match the scale factor of the
 | 
| +  // IOSurface.
 | 
| +  if (compositing_iosurface_layer_)
 | 
| +    [compositing_iosurface_layer_ updateScaleFactor];
 | 
| +
 | 
|    if (!last_frame_was_accelerated_) {
 | 
|      last_frame_was_accelerated_ = true;
 | 
|  
 | 
| -    // Need to wipe the software view with transparency to expose the GL
 | 
| -    // underlay. Invalidate the whole window to do that.
 | 
| -    [cocoa_view_ setNeedsDisplay:YES];
 | 
| +    if (!use_core_animation_) {
 | 
| +      // Need to wipe the software view with transparency to expose the GL
 | 
| +      // underlay. Invalidate the whole window to do that.
 | 
| +      [cocoa_view_ setNeedsDisplay:YES];
 | 
| +    }
 | 
|  
 | 
|      // Delete software backingstore.
 | 
|      BackingStoreManager::RemoveBackingStore(render_widget_host_);
 | 
| @@ -1469,9 +1541,17 @@ void RenderWidgetHostViewMac::GotSoftwareFrame() {
 | 
|      AckPendingSwapBuffers();
 | 
|  
 | 
|      // Forget IOSurface since we are drawing a software frame now.
 | 
| -    if (compositing_iosurface_.get() &&
 | 
| -        compositing_iosurface_->HasIOSurface()) {
 | 
| -      compositing_iosurface_->ClearDrawable();
 | 
| +    if (use_core_animation_) {
 | 
| +      compositing_iosurface_.reset();
 | 
| +      if (compositing_iosurface_layer_)
 | 
| +        [compositing_iosurface_layer_ disableCompositing];
 | 
| +      compositing_iosurface_layer_.reset();
 | 
| +    }
 | 
| +    else {
 | 
| +      if (compositing_iosurface_ &&
 | 
| +          compositing_iosurface_->HasIOSurface()) {
 | 
| +        compositing_iosurface_->ClearDrawable();
 | 
| +      }
 | 
|      }
 | 
|    }
 | 
|  }
 | 
| @@ -1591,7 +1671,7 @@ gfx::Rect RenderWidgetHostViewMac::GetScaledOpenGLPixelRect(
 | 
|    src_gl_subrect.set_y(GetViewBounds().height() - rect.bottom());
 | 
|  
 | 
|    return gfx::ToEnclosingRect(gfx::ScaleRect(src_gl_subrect,
 | 
| -                                             ScaleFactor(cocoa_view_)));
 | 
| +                                             scale_factor()));
 | 
|  }
 | 
|  
 | 
|  }  // namespace content
 | 
| @@ -2143,7 +2223,9 @@ gfx::Rect RenderWidgetHostViewMac::GetScaledOpenGLPixelRect(
 | 
|    // We're messing with the window, so do this to ensure no flashes. This one
 | 
|    // prevents a flash when the current tab is closed.
 | 
|    NSWindow* oldWindow = [self window];
 | 
| -  [oldWindow disableScreenUpdatesUntilFlush];
 | 
| +
 | 
| +  if (!renderWidgetHostView_->use_core_animation_)
 | 
| +    [oldWindow disableScreenUpdatesUntilFlush];
 | 
|  
 | 
|    NSNotificationCenter* notificationCenter =
 | 
|        [NSNotificationCenter defaultCenter];
 | 
| @@ -2194,6 +2276,7 @@ gfx::Rect RenderWidgetHostViewMac::GetScaledOpenGLPixelRect(
 | 
|    if (backingStore)  // NULL in hardware path.
 | 
|      backingStore->ScaleFactorChanged(scaleFactor);
 | 
|  
 | 
| +  [self updateSoftwareLayerScaleFactor];
 | 
|    renderWidgetHostView_->render_widget_host_->NotifyScreenInfoChanged();
 | 
|  }
 | 
|  
 | 
| @@ -2250,12 +2333,16 @@ gfx::Rect RenderWidgetHostViewMac::GetScaledOpenGLPixelRect(
 | 
|    [self setNeedsDisplayInRect:renderWidgetHostView_->invalid_rect_];
 | 
|    renderWidgetHostView_->call_set_needs_display_in_rect_pending_ = false;
 | 
|    renderWidgetHostView_->invalid_rect_ = NSZeroRect;
 | 
| +
 | 
| +  if (renderWidgetHostView_->compositing_iosurface_layer_)
 | 
| +    [renderWidgetHostView_->compositing_iosurface_layer_ setNeedsDisplay];
 | 
|  }
 | 
|  
 | 
|  // Fills with white the parts of the area to the right and bottom for |rect|
 | 
|  // that intersect |damagedRect|.
 | 
|  - (void)fillBottomRightRemainderOfRect:(gfx::Rect)rect
 | 
| -                             dirtyRect:(gfx::Rect)damagedRect {
 | 
| +                             dirtyRect:(gfx::Rect)damagedRect
 | 
| +                             inContext:(CGContextRef)context {
 | 
|    if (damagedRect.right() > rect.right()) {
 | 
|      int x = std::max(rect.right(), damagedRect.x());
 | 
|      int y = std::min(rect.bottom(), damagedRect.bottom());
 | 
| @@ -2274,8 +2361,9 @@ gfx::Rect RenderWidgetHostViewMac::GetScaledOpenGLPixelRect(
 | 
|      }
 | 
|  
 | 
|      NSRect r = [self flipRectToNSRect:gfx::Rect(x, y, width, height)];
 | 
| -    [[NSColor whiteColor] set];
 | 
| -    NSRectFill(r);
 | 
| +    CGContextSetFillColorWithColor(context,
 | 
| +                                   CGColorGetConstantColor(kCGColorWhite));
 | 
| +    CGContextFillRect(context, NSRectToCGRect(r));
 | 
|    }
 | 
|    if (damagedRect.bottom() > rect.bottom()) {
 | 
|      int x = damagedRect.x();
 | 
| @@ -2295,13 +2383,16 @@ gfx::Rect RenderWidgetHostViewMac::GetScaledOpenGLPixelRect(
 | 
|      }
 | 
|  
 | 
|      NSRect r = [self flipRectToNSRect:gfx::Rect(x, y, width, height)];
 | 
| -    [[NSColor whiteColor] set];
 | 
| -    NSRectFill(r);
 | 
| +    CGContextSetFillColorWithColor(context,
 | 
| +                                   CGColorGetConstantColor(kCGColorWhite));
 | 
| +    CGContextFillRect(context, NSRectToCGRect(r));
 | 
|    }
 | 
|  }
 | 
|  
 | 
|  - (void)drawRect:(NSRect)dirtyRect {
 | 
|    TRACE_EVENT0("browser", "RenderWidgetHostViewCocoa::drawRect");
 | 
| +  DCHECK(!renderWidgetHostView_->use_core_animation_);
 | 
| +
 | 
|    if (!renderWidgetHostView_->render_widget_host_) {
 | 
|      // TODO(shess): Consider using something more noticable?
 | 
|      [[NSColor whiteColor] set];
 | 
| @@ -2322,7 +2413,7 @@ gfx::Rect RenderWidgetHostViewMac::GetScaledOpenGLPixelRect(
 | 
|    const gfx::Rect damagedRect([self flipNSRectToRect:dirtyRect]);
 | 
|  
 | 
|    if (renderWidgetHostView_->last_frame_was_accelerated_ &&
 | 
| -      renderWidgetHostView_->compositing_iosurface_.get()) {
 | 
| +      renderWidgetHostView_->compositing_iosurface_) {
 | 
|      if (renderWidgetHostView_->allow_overlapping_views_) {
 | 
|        // If overlapping views need to be allowed, punch a hole in the window
 | 
|        // to expose the GL underlay.
 | 
| @@ -2337,19 +2428,21 @@ gfx::Rect RenderWidgetHostViewMac::GetScaledOpenGLPixelRect(
 | 
|        NSRectFill(dirtyRect);
 | 
|      }
 | 
|  
 | 
| -    content::CompositingIOSurfaceMac::SurfaceOrder order =
 | 
| -        renderWidgetHostView_->allow_overlapping_views_
 | 
| -        ? content::CompositingIOSurfaceMac::SURFACE_ORDER_BELOW_WINDOW
 | 
| -        : content::CompositingIOSurfaceMac::SURFACE_ORDER_ABOVE_WINDOW;
 | 
|      renderWidgetHostView_->compositing_iosurface_->DrawIOSurface(
 | 
| -        self,
 | 
| -        ScaleFactor(self),
 | 
| -        renderWidgetHostView_->window_number(),
 | 
| -        order,
 | 
| -        renderWidgetHostView_->frame_subscriber());
 | 
| +        renderWidgetHostView_.get());
 | 
|      return;
 | 
|    }
 | 
|  
 | 
| +  CGContextRef context = static_cast<CGContextRef>(
 | 
| +      [[NSGraphicsContext currentContext] graphicsPort]);
 | 
| +  [self drawBackingStore:backingStore
 | 
| +               dirtyRect:NSRectToCGRect(dirtyRect)
 | 
| +               inContext:context];
 | 
| +}
 | 
| +
 | 
| +- (void)drawBackingStore:(BackingStoreMac*)backingStore
 | 
| +               dirtyRect:(CGRect)dirtyRect
 | 
| +               inContext:(CGContextRef)context {
 | 
|    if (backingStore) {
 | 
|      // Note: All coordinates are in view units, not pixels.
 | 
|      gfx::Rect bitmapRect(0, 0,
 | 
| @@ -2361,13 +2454,13 @@ gfx::Rect RenderWidgetHostViewMac::GetScaledOpenGLPixelRect(
 | 
|      // smaller and the renderer hasn't yet repainted.
 | 
|      int yOffset = NSHeight([self bounds]) - backingStore->size().height();
 | 
|  
 | 
| +    NSRect nsDirtyRect = NSRectFromCGRect(dirtyRect);
 | 
| +    const gfx::Rect damagedRect([self flipNSRectToRect:nsDirtyRect]);
 | 
| +
 | 
|      gfx::Rect paintRect = gfx::IntersectRects(bitmapRect, damagedRect);
 | 
|      if (!paintRect.IsEmpty()) {
 | 
|        // if we have a CGLayer, draw that into the window
 | 
|        if (backingStore->cg_layer()) {
 | 
| -        CGContextRef context = static_cast<CGContextRef>(
 | 
| -            [[NSGraphicsContext currentContext] graphicsPort]);
 | 
| -
 | 
|          // TODO: add clipping to dirtyRect if it improves drawing performance.
 | 
|          CGContextDrawLayerAtPoint(context, CGPointMake(0.0, yOffset),
 | 
|                                    backingStore->cg_layer());
 | 
| @@ -2375,8 +2468,6 @@ gfx::Rect RenderWidgetHostViewMac::GetScaledOpenGLPixelRect(
 | 
|          // if we haven't created a layer yet, draw the cached bitmap into
 | 
|          // the window.  The CGLayer will be created the next time the renderer
 | 
|          // paints.
 | 
| -        CGContextRef context = static_cast<CGContextRef>(
 | 
| -            [[NSGraphicsContext currentContext] graphicsPort]);
 | 
|          base::mac::ScopedCFTypeRef<CGImageRef> image(
 | 
|              CGBitmapContextCreateImage(backingStore->cg_bitmap()));
 | 
|          CGRect imageRect = bitmapRect.ToCGRect();
 | 
| @@ -2386,7 +2477,9 @@ gfx::Rect RenderWidgetHostViewMac::GetScaledOpenGLPixelRect(
 | 
|      }
 | 
|  
 | 
|      // Fill the remaining portion of the damagedRect with white
 | 
| -    [self fillBottomRightRemainderOfRect:bitmapRect dirtyRect:damagedRect];
 | 
| +    [self fillBottomRightRemainderOfRect:bitmapRect
 | 
| +                               dirtyRect:damagedRect
 | 
| +                               inContext:context];
 | 
|  
 | 
|      if (!renderWidgetHostView_->whiteout_start_time_.is_null()) {
 | 
|        base::TimeDelta whiteout_duration = base::TimeTicks::Now() -
 | 
| @@ -2409,8 +2502,9 @@ gfx::Rect RenderWidgetHostViewMac::GetScaledOpenGLPixelRect(
 | 
|            base::TimeTicks();
 | 
|      }
 | 
|    } else {
 | 
| -    [[NSColor whiteColor] set];
 | 
| -    NSRectFill(dirtyRect);
 | 
| +    CGContextSetFillColorWithColor(context,
 | 
| +                                   CGColorGetConstantColor(kCGColorWhite));
 | 
| +    CGContextFillRect(context, dirtyRect);
 | 
|      if (renderWidgetHostView_->whiteout_start_time_.is_null())
 | 
|        renderWidgetHostView_->whiteout_start_time_ = base::TimeTicks::Now();
 | 
|    }
 | 
| @@ -3383,6 +3477,52 @@ extern NSString *NSTextInputReplacementRangeAttributeName;
 | 
|    renderWidgetHostView_->KillSelf();
 | 
|  }
 | 
|  
 | 
| +- (void)updateSoftwareLayerScaleFactor {
 | 
| +  if (![renderWidgetHostView_->software_layer_
 | 
| +          respondsToSelector:@selector(setContentsScale:)])
 | 
| +    return;
 | 
| +
 | 
| +  ScopedCAActionDisabler disabler;
 | 
| +  [renderWidgetHostView_->software_layer_ setContentsScale:deviceScaleFactor_];
 | 
| +}
 | 
| +
 | 
| +// Delegate methods for the software CALayer
 | 
| +- (void)drawLayer:(CALayer*)layer
 | 
| +        inContext:(CGContextRef)context {
 | 
| +  DCHECK(renderWidgetHostView_->use_core_animation_);
 | 
| +  DCHECK([layer isEqual:renderWidgetHostView_->software_layer_]);
 | 
| +
 | 
| +  CGRect clipRect = CGContextGetClipBoundingBox(context);
 | 
| +
 | 
| +  if (!renderWidgetHostView_->render_widget_host_ ||
 | 
| +      renderWidgetHostView_->is_hidden()) {
 | 
| +    CGContextSetFillColorWithColor(context,
 | 
| +                                   CGColorGetConstantColor(kCGColorWhite));
 | 
| +    CGContextFillRect(context, clipRect);
 | 
| +    return;
 | 
| +  }
 | 
| +
 | 
| +  renderWidgetHostView_->about_to_validate_and_paint_ = true;
 | 
| +  BackingStoreMac* backingStore = static_cast<BackingStoreMac*>(
 | 
| +      renderWidgetHostView_->render_widget_host_->GetBackingStore(true));
 | 
| +  renderWidgetHostView_->about_to_validate_and_paint_ = false;
 | 
| +
 | 
| +  [self drawBackingStore:backingStore
 | 
| +               dirtyRect:clipRect
 | 
| +               inContext:context];
 | 
| +}
 | 
| +
 | 
| +- (void)setNeedsDisplay:(BOOL)flag {
 | 
| +  [renderWidgetHostView_->software_layer_ setNeedsDisplay];
 | 
| +  [super setNeedsDisplay:flag];
 | 
| +}
 | 
| +
 | 
| +- (void)setNeedsDisplayInRect:(NSRect)rect {
 | 
| +  [renderWidgetHostView_->software_layer_
 | 
| +      setNeedsDisplayInRect:NSRectToCGRect(rect)];
 | 
| +  [super setNeedsDisplayInRect:rect];
 | 
| +}
 | 
| +
 | 
|  @end
 | 
|  
 | 
|  //
 | 
| @@ -3413,4 +3553,10 @@ extern NSString *NSTextInputReplacementRangeAttributeName;
 | 
|    return YES;
 | 
|  }
 | 
|  
 | 
| +- (BOOL)isOpaque {
 | 
| +  if (renderWidgetHostView_->use_core_animation_)
 | 
| +    return YES;
 | 
| +  return [super isOpaque];
 | 
| +}
 | 
| +
 | 
|  @end
 | 
| 
 |