Chromium Code Reviews| 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 200c1aa3355e08033196f1db3924b6b8a37b6592..6d452f6cca7dd1b543f8c024238bdba1c2dee0d6 100644 |
| --- a/content/browser/renderer_host/render_widget_host_view_mac.mm |
| +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm |
| @@ -8,6 +8,7 @@ |
| #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" |
| @@ -25,6 +26,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,6 +41,7 @@ |
| #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" |
| @@ -53,6 +57,7 @@ |
| #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" |
| #include "ui/gfx/size_conversions.h" |
| #include "ui/surface/io_surface_support_mac.h" |
| +#include "ui/base/cocoa/animation_utils.h" |
|
Avi (use Gerrit)
2013/05/31 23:59:58
alphabetize
ccameron
2013/06/01 00:29:45
Done.
|
| #include "webkit/plugins/npapi/webplugin.h" |
| using content::BackingStoreMac; |
| @@ -77,6 +82,10 @@ using WebKit::WebMouseWheelEvent; |
| - (BOOL)isSpeaking; |
| @end |
| +@interface CALayer (LionAPI) |
| +- (void)setContentsScale:(CGFloat)contentsScale; |
| +@end |
| + |
| // 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 |
| @@ -144,6 +153,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,10 +379,14 @@ 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), |
| fullscreen_parent_host_view_(NULL) { |
| + use_core_animation_ = CommandLine::ForCurrentProcess()->HasSwitch( |
| + switches::kUseCoreAnimation); |
| + |
| // |cocoa_view_| owns us and we will be deleted when |cocoa_view_| |
| // goes away. Since we autorelease it, our caller must put |
| // |GetNativeView()| into the view hierarchy right after calling us. |
| @@ -381,6 +398,13 @@ RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget) |
| 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 +418,7 @@ void RenderWidgetHostViewMac::SetDelegate( |
| } |
| void RenderWidgetHostViewMac::SetAllowOverlappingViews(bool overlapping) { |
| + DCHECK(!overlapping || !use_core_animation_); |
| allow_overlapping_views_ = overlapping; |
| } |
| @@ -512,6 +537,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_; |
| } |
| @@ -526,7 +555,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() { |
| @@ -551,7 +584,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(); |
| } |
| @@ -1043,9 +1077,8 @@ void RenderWidgetHostViewMac::PluginImeCompositionCompleted( |
| } |
| } |
| -bool RenderWidgetHostViewMac::CompositorSwapBuffers(uint64 surface_handle, |
| - const gfx::Size& size, |
| - float scale_factor) { |
| +bool RenderWidgetHostViewMac::CompositorSwapBuffers( |
| + uint64 surface_handle, const gfx::Size& size, float surface_scale_factor) { |
| if (is_hidden_) |
| return true; |
| @@ -1060,7 +1093,7 @@ bool RenderWidgetHostViewMac::CompositorSwapBuffers(uint64 surface_handle, |
| if (frame_subscriber_->ShouldCaptureFrame(present_time, |
| &frame, &callback)) { |
| compositing_iosurface_->SetIOSurface( |
| - surface_handle, size, scale_factor); |
| + surface_handle, size, surface_scale_factor); |
| compositing_iosurface_->CopyToVideoFrame( |
| gfx::Rect(size), frame, |
| base::Bind(callback, present_time)); |
| @@ -1091,18 +1124,43 @@ bool RenderWidgetHostViewMac::CompositorSwapBuffers(uint64 surface_handle, |
| bool should_post_notification = false; |
| if (!compositing_iosurface_) { |
| - CompositingIOSurfaceMac::SurfaceOrder order = allow_overlapping_views_ ? |
| - CompositingIOSurfaceMac::SURFACE_ORDER_BELOW_WINDOW : |
| - CompositingIOSurfaceMac::SURFACE_ORDER_ABOVE_WINDOW; |
| - compositing_iosurface_.reset( |
| - CompositingIOSurfaceMac::Create(window_number(), order)); |
| + 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 { |
| + CompositingIOSurfaceMac::SurfaceOrder order = allow_overlapping_views_ ? |
| + CompositingIOSurfaceMac::SURFACE_ORDER_BELOW_WINDOW : |
| + CompositingIOSurfaceMac::SURFACE_ORDER_ABOVE_WINDOW; |
| + compositing_iosurface_.reset( |
| + CompositingIOSurfaceMac::Create(window_number(), order)); |
| + } |
| 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); |
| + compositing_iosurface_->SetIOSurface( |
| + surface_handle, size, surface_scale_factor); |
| + |
| + // 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(); |
| @@ -1116,14 +1174,12 @@ bool RenderWidgetHostViewMac::CompositorSwapBuffers(uint64 surface_handle, |
| // 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] |
| @@ -1131,6 +1187,10 @@ bool RenderWidgetHostViewMac::CompositorSwapBuffers(uint64 surface_handle, |
| [[cocoa_view_ delegate] compositingIOSurfaceCreated]; |
| } |
| + // Don't ack the new frame until it is drawn. |
| + if (use_core_animation_) |
| + return false; |
| + |
| return true; |
| } |
| @@ -1341,6 +1401,9 @@ void RenderWidgetHostViewMac::AcceleratedSurfaceSuspend() { |
| void RenderWidgetHostViewMac::AcceleratedSurfaceRelease() { |
| compositing_iosurface_.reset(); |
| + if (compositing_iosurface_layer_) |
| + [compositing_iosurface_layer_ disableCompositing]; |
| + compositing_iosurface_layer_.reset(); |
| } |
| bool RenderWidgetHostViewMac::HasAcceleratedSurface( |
| @@ -1444,12 +1507,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_); |
| @@ -1463,9 +1533,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_.get() && |
|
sail
2013/05/31 23:59:14
don't need the .get()
ccameron
2013/06/01 00:29:45
Removed all instances of compositing_iosurface_.ge
|
| + compositing_iosurface_->HasIOSurface()) { |
| + compositing_iosurface_->ClearDrawable(); |
| + } |
| } |
| } |
| } |
| @@ -1585,7 +1663,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 |
| @@ -1610,6 +1688,21 @@ gfx::Rect RenderWidgetHostViewMac::GetScaledOpenGLPixelRect( |
| focusedPluginIdentifier_ = -1; |
| deviceScaleFactor_ = ScaleFactor(self); |
| + if (renderWidgetHostView_->use_core_animation_) { |
| + CALayer* layer = [CALayer layer]; |
| + layer.backgroundColor = CGColorGetConstantColor(kCGColorWhite); |
| + [self setLayer:layer]; |
| + [self setWantsLayer:YES]; |
| + |
| + softwareLayer_.reset([[CALayer alloc] init]); |
| + [softwareLayer_ setDelegate:self]; |
| + [softwareLayer_ setAutoresizingMask:kCALayerWidthSizable | |
| + kCALayerHeightSizable]; |
| + [softwareLayer_ setContentsGravity:kCAGravityTopLeft]; |
| + [[self layer] addSublayer:softwareLayer_]; |
| + [self updateSoftwareLayerScaleFactor]; |
| + } |
| + |
| // OpenGL support: |
| if ([self respondsToSelector: |
| @selector(setWantsBestResolutionOpenGLSurface:)]) { |
| @@ -2131,7 +2224,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]; |
| @@ -2182,6 +2277,7 @@ gfx::Rect RenderWidgetHostViewMac::GetScaledOpenGLPixelRect( |
| if (backingStore) // NULL in hardware path. |
| backingStore->ScaleFactorChanged(scaleFactor); |
| + [self updateSoftwareLayerScaleFactor]; |
| renderWidgetHostView_->render_widget_host_->NotifyScreenInfoChanged(); |
| } |
| @@ -2238,12 +2334,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()); |
| @@ -2262,8 +2362,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(); |
| @@ -2283,13 +2384,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]; |
| @@ -2325,19 +2429,22 @@ 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 { |
| + |
|
sail
2013/05/31 23:59:14
remove new line?
Avi (use Gerrit)
2013/05/31 23:59:58
no blank line
ccameron
2013/06/01 00:29:45
Done.
|
| if (backingStore) { |
| // Note: All coordinates are in view units, not pixels. |
| gfx::Rect bitmapRect(0, 0, |
| @@ -2349,13 +2456,16 @@ gfx::Rect RenderWidgetHostViewMac::GetScaledOpenGLPixelRect( |
| // smaller and the renderer hasn't yet repainted. |
| int yOffset = NSHeight([self bounds]) - backingStore->size().height(); |
| + NSRect nsDirtyRect = NSMakeRect(dirtyRect.origin.x, |
| + dirtyRect.origin.y, |
| + dirtyRect.size.width, |
| + dirtyRect.size.height); |
| + 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()); |
| @@ -2363,8 +2473,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(); |
| @@ -2374,7 +2482,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() - |
| @@ -2397,8 +2507,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(); |
| } |
| @@ -3371,6 +3482,50 @@ extern NSString *NSTextInputReplacementRangeAttributeName; |
| renderWidgetHostView_->KillSelf(); |
| } |
| +- (void)updateSoftwareLayerScaleFactor { |
| + if (![softwareLayer_ respondsToSelector:@selector(setContentsScale:)]) |
| + return; |
| + |
| + ScopedCAActionDisabler disabler; |
| + [softwareLayer_ setContentsScale:deviceScaleFactor_]; |
| +} |
| + |
| +// Delegate methods for the software CALayer |
| +- (void)drawLayer:(CALayer*)layer |
| + inContext:(CGContextRef)context { |
| + DCHECK(renderWidgetHostView_->use_core_animation_); |
| + DCHECK([layer isEqual:softwareLayer_]); |
| + |
| + 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 { |
| + [softwareLayer_ setNeedsDisplay]; |
| + [super setNeedsDisplay:flag]; |
| +} |
| + |
| +- (void)setNeedsDisplayInRect:(NSRect)rect { |
| + [softwareLayer_ setNeedsDisplayInRect:NSRectToCGRect(rect)]; |
| + [super setNeedsDisplayInRect:rect]; |
| +} |
| + |
| @end |
| // |
| @@ -3401,4 +3556,10 @@ extern NSString *NSTextInputReplacementRangeAttributeName; |
| return YES; |
| } |
| +- (BOOL)isOpaque { |
| + if (renderWidgetHostView_->use_core_animation_) |
| + return YES; |
| + return [super isOpaque]; |
| +} |
| + |
| @end |