Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(302)

Unified Diff: content/browser/renderer_host/render_widget_host_view_mac.mm

Issue 297573003: Make delegated software renderer work on Mac (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix windows build Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 b50fd999cff0582dc07c2c22a923cb37f611db70..50f1ad4cd968f6095ef39740062b6f710dce74ac 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -611,8 +611,7 @@ void RenderWidgetHostViewMac::EnsureSoftwareLayer() {
if (software_layer_ || !use_core_animation_)
return;
- software_layer_.reset([[SoftwareLayer alloc]
- initWithRenderWidgetHostViewMac:this]);
+ software_layer_.reset([[SoftwareLayer alloc] init]);
DCHECK(software_layer_);
// Disable the fade-in animation as the layer is added.
@@ -872,7 +871,6 @@ void RenderWidgetHostViewMac::WasShown() {
// Call setNeedsDisplay before pausing for new frames to come in -- if any
// do, and are drawn, then the needsDisplay bit will be cleared.
- [software_layer_ setNeedsDisplay];
[compositing_iosurface_layer_ setNeedsDisplay];
PauseForPendingResizeOrRepaintsAndDraw();
@@ -1574,6 +1572,50 @@ void RenderWidgetHostViewMac::CompositorSwapBuffers(
LayoutLayers();
}
+void RenderWidgetHostViewMac::GotBrowserCompositorSoftwareFrame(
+ cc::SoftwareFrameData* frame_data,
+ float scale_factor,
+ SkCanvas* canvas) {
+ if (!frame_data || !canvas)
+ return;
+
+ // Disable animating the contents change or the scale factor change.
+ ScopedCAActionDisabler disabler;
+ EnsureSoftwareLayer();
+
+ // Set the contents of the software CALayer to be a CGImage with the provided
+ // pixel data.
+ SkImageInfo info;
+ size_t row_bytes;
+ const void* pixels = canvas->peekPixels(&info, &row_bytes);
+ base::ScopedCFTypeRef<CGDataProviderRef> data_provider(
+ CGDataProviderCreateWithData(
+ NULL, pixels, 4 * info.fWidth * info.fHeight, NULL));
piman 2014/05/20 07:04:17 Doesn't this assume that CoreAnimation won't look
ccameron 2014/05/20 19:15:50 The documentation is very unclear, but this does a
+ base::ScopedCFTypeRef<CGImageRef> image(
+ CGImageCreate(info.fWidth,
+ info.fHeight,
+ 8,
+ 32,
+ row_bytes,
+ base::mac::GetSystemColorSpace(),
+ kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host,
+ data_provider,
+ NULL,
+ false,
+ kCGRenderingIntentDefault));
+ [software_layer_ setContents:(id)image.get()];
+
+ // Set the contents scale of the software CALayer.
+ if ([software_layer_ respondsToSelector:(@selector(contentsScale))] &&
+ [software_layer_ respondsToSelector:(@selector(setContentsScale:))] &&
+ [software_layer_ contentsScale] != scale_factor) {
+ [software_layer_ setContentsScale:scale_factor];
+ }
+
+ LayoutLayers();
+ DestroyCompositedIOSurfaceAndLayer(kDestroyContext);
+}
+
void RenderWidgetHostViewMac::DrawIOSurfaceWithoutCoreAnimation() {
CHECK(!use_core_animation_);
CHECK(compositing_iosurface_);
@@ -1897,6 +1939,8 @@ bool RenderWidgetHostViewMac::HasAcceleratedSurface(
void RenderWidgetHostViewMac::OnSwapCompositorFrame(
uint32 output_surface_id, scoped_ptr<cc::CompositorFrame> frame) {
+ TRACE_EVENT0("browser", "RenderWidgetHostViewMac::OnSwapCompositorFrame");
+
if (frame->delegated_frame_data) {
if (!compositor_) {
compositor_.reset(new ui::Compositor(cocoa_view_));
@@ -1936,6 +1980,48 @@ void RenderWidgetHostViewMac::OnSwapCompositorFrame(
AddPendingLatencyInfo(frame->metadata.latency_info);
GotSoftwareFrame();
+ if (use_core_animation_) {
+ // Disable animating the contents change or the scale factor change.
+ ScopedCAActionDisabler disabler;
+ EnsureSoftwareLayer();
+
+ // Set the contents of the software CALayer to be a CGImage with the
+ // provided pixel data.
+ gfx::Size size_in_pixels =
+ software_frame_manager_->GetCurrentFrameSizeInPixels();
+ base::ScopedCFTypeRef<CGDataProviderRef> data_provider(
+ CGDataProviderCreateWithData(
+ NULL,
+ software_frame_manager_->GetCurrentFramePixels(),
+ 4 * size_in_pixels.width() * size_in_pixels.height(),
+ NULL));
+ base::ScopedCFTypeRef<CGImageRef> image(CGImageCreate(
+ size_in_pixels.width(),
+ size_in_pixels.height(),
+ 8,
+ 32,
+ 4 * size_in_pixels.width(),
+ base::mac::GetSystemColorSpace(),
+ kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host,
+ data_provider,
+ NULL,
+ false,
+ kCGRenderingIntentDefault));
+ [software_layer_ setContents:(id)image.get()];
+
+ // Set the contents scale of the software CALayer.
+ if ([software_layer_ respondsToSelector:(@selector(contentsScale))] &&
+ [software_layer_ respondsToSelector:(@selector(setContentsScale:))] &&
+ [software_layer_ contentsScale] !=
+ frame->metadata.device_scale_factor) {
+ [software_layer_ setContentsScale:frame->metadata.device_scale_factor];
+ }
+
+ // Send latency information to the host immediately, as there will be no
+ // subsequent draw call in which to do so.
+ SendPendingLatencyInfoToHost();
+ }
+
cc::CompositorFrameAck ack;
RenderWidgetHostImpl::SendSwapCompositorFrameAck(
render_widget_host_->GetRoutingID(),
@@ -2077,6 +2163,8 @@ void RenderWidgetHostViewMac::GotAcceleratedFrame() {
}
void RenderWidgetHostViewMac::GotSoftwareFrame() {
+ TRACE_EVENT0("browser", "RenderWidgetHostViewMac::GotSoftwareFrame");
+
if (!render_widget_host_)
return;
@@ -2088,7 +2176,6 @@ void RenderWidgetHostViewMac::GotSoftwareFrame() {
// happen before the frame be acked, otherwise the new frame will likely be
// ready before the drawing is complete, thrashing the browser main thread.
if (use_core_animation_) {
- [software_layer_ setNeedsDisplay];
[software_layer_ displayIfNeeded];
} else {
[cocoa_view_ setNeedsDisplay:YES];
@@ -2333,15 +2420,14 @@ void RenderWidgetHostViewMac::TickPendingLatencyInfoDelay() {
[compositing_iosurface_layer_ gotNewFrame];
}
if (software_layer_) {
- // In software mode, setNeedsDisplay will almost immediately result in the
- // layer's draw function being called, so manually insert a pretend-vsync
- // at 60 Hz.
+ // In software mode there is not an explicit setNeedsDisplay/display loop,
+ // so just wait a pretend-vsync at 60 Hz.
base::MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&RenderWidgetHostViewMac::TickPendingLatencyInfoDelay,
pending_latency_info_delay_weak_ptr_factory_.GetWeakPtr()),
base::TimeDelta::FromMilliseconds(1000/60));
- [software_layer_ setNeedsDisplay];
+ SendPendingLatencyInfoToHost();
}
}
@@ -2447,17 +2533,6 @@ void RenderWidgetHostViewMac::LayoutLayers() {
}
}
- // Dynamically update the software layer's contents scale to match the
- // software frame.
- if (software_frame_manager_->HasCurrentFrame() &&
- [software_layer_ respondsToSelector:(@selector(contentsScale))] &&
- [software_layer_ respondsToSelector:(@selector(setContentsScale:))]) {
- if (software_frame_manager_->GetCurrentFrameDeviceScaleFactor() !=
- [software_layer_ contentsScale]) {
- [software_layer_ setContentsScale:
- software_frame_manager_->GetCurrentFrameDeviceScaleFactor()];
- }
- }
// Changing the software layer's bounds and position doesn't always result
// in the layer being anchored to the top-left. Set the layer's frame
// explicitly, since this is more reliable in practice.
@@ -2466,7 +2541,6 @@ void RenderWidgetHostViewMac::LayoutLayers() {
new_background_frame, [software_layer_ frame]);
if (frame_changed) {
[software_layer_ setFrame:new_background_frame];
- [software_layer_ setNeedsDisplay];
}
}
}
@@ -3319,6 +3393,13 @@ SkBitmap::Config RenderWidgetHostViewMac::PreferredReadbackFormat() {
params.latency_info);
}
+- (void)gotSoftwareFrame:(cc::SoftwareFrameData*)frame_data
+ withScaleFactor:(float)scale_factor
+ withCanvas:(SkCanvas*)canvas {
+ renderWidgetHostView_->GotBrowserCompositorSoftwareFrame(
+ frame_data, scale_factor, canvas);
+}
+
- (void)drawRect:(NSRect)dirtyRect {
TRACE_EVENT0("browser", "RenderWidgetHostViewCocoa::drawRect");
DCHECK(!renderWidgetHostView_->use_core_animation_);
@@ -4389,46 +4470,21 @@ extern NSString *NSTextInputReplacementRangeAttributeName;
@implementation SoftwareLayer
-- (id)initWithRenderWidgetHostViewMac:(content::RenderWidgetHostViewMac*)r {
+- (id)init {
if (self = [super init]) {
- renderWidgetHostView_ = r;
-
[self setBackgroundColor:CGColorGetConstantColor(kCGColorWhite)];
[self setAnchorPoint:CGPointMake(0, 0)];
// Setting contents gravity is necessary to prevent the layer from being
// scaled during dyanmic resizes (especially with devtools open).
[self setContentsGravity:kCAGravityTopLeft];
- if (renderWidgetHostView_->software_frame_manager_->HasCurrentFrame() &&
- [self respondsToSelector:(@selector(setContentsScale:))]) {
- [self setContentsScale:renderWidgetHostView_->software_frame_manager_->
- GetCurrentFrameDeviceScaleFactor()];
- }
-
- // Ensure that the transition between frames not be animated.
- [self setActions:@{ @"contents" : [NSNull null] }];
}
return self;
}
-- (void)drawInContext:(CGContextRef)context {
- TRACE_EVENT0("browser", "SoftwareLayer::drawInContext");
-
- CGRect clipRect = CGContextGetClipBoundingBox(context);
- if (renderWidgetHostView_) {
- [renderWidgetHostView_->cocoa_view() drawWithDirtyRect:clipRect
- inContext:context];
- } else {
- CGContextSetFillColorWithColor(context,
- CGColorGetConstantColor(kCGColorWhite));
- CGContextFillRect(context, clipRect);
- }
-}
-
- (void)disableRendering {
// Disable the fade-out animation as the layer is removed.
ScopedCAActionDisabler disabler;
[self removeFromSuperlayer];
- renderWidgetHostView_ = nil;
}
@end // implementation SoftwareLayer

Powered by Google App Engine
This is Rietveld 408576698