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

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

Issue 25942002: Make software compositing work on Mac. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix windows resolve Created 7 years, 2 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 02c66aa03f9ff454a992bc44371f0b660e35358d..d632390a9acadfd123bd65daffe39def6c545f13 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -46,6 +46,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/browser/user_metrics.h"
#include "content/public/common/content_switches.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
@@ -426,7 +427,10 @@ RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget)
weak_factory_(this),
fullscreen_parent_host_view_(NULL),
pending_swap_buffers_acks_weak_factory_(this),
- next_swap_ack_time_(base::Time::Now()) {
+ next_swap_ack_time_(base::Time::Now()),
+ software_frame_weak_ptr_factory_(this) {
+ software_frame_manager_.reset(new SoftwareFrameManager(
+ software_frame_weak_ptr_factory_.GetWeakPtr()));
// |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.
@@ -732,6 +736,7 @@ void RenderWidgetHostViewMac::WasShown() {
if (web_contents_switch_paint_time_.is_null())
web_contents_switch_paint_time_ = base::TimeTicks::Now();
render_widget_host_->WasShown();
+ software_frame_manager_->SetVisibility(true);
// We're messing with the window, so do this to ensure no flashes.
if (!use_core_animation_)
@@ -751,6 +756,7 @@ void RenderWidgetHostViewMac::WasHidden() {
// If we have a renderer, then inform it that we are being hidden so it can
// reduce its resource utilization.
render_widget_host_->WasHidden();
+ software_frame_manager_->SetVisibility(false);
// There can be a transparent flash as this view is removed and the next is
// added, because of OSX windowing races between displaying the contents of
@@ -1650,17 +1656,50 @@ void RenderWidgetHostViewMac::AcceleratedSurfaceRelease() {
bool RenderWidgetHostViewMac::HasAcceleratedSurface(
const gfx::Size& desired_size) {
- return last_frame_was_accelerated_ &&
- compositing_iosurface_ &&
- compositing_iosurface_->HasIOSurface() &&
- (desired_size.IsEmpty() ||
- compositing_iosurface_->dip_io_surface_size() == desired_size);
+ if (last_frame_was_accelerated_) {
+ return compositing_iosurface_ &&
+ compositing_iosurface_->HasIOSurface() &&
+ (desired_size.IsEmpty() ||
+ compositing_iosurface_->dip_io_surface_size() == desired_size);
+ } else {
+ return (software_frame_manager_->HasCurrentFrame() &&
+ (desired_size.IsEmpty() ||
+ software_frame_manager_->GetCurrentFrameSizeInDIP() ==
+ desired_size));
+ }
+ return false;
}
void RenderWidgetHostViewMac::AboutToWaitForBackingStoreMsg() {
AckPendingSwapBuffers();
}
+void RenderWidgetHostViewMac::OnSwapCompositorFrame(
+ uint32 output_surface_id, scoped_ptr<cc::CompositorFrame> frame) {
+ // Only software compositor frames are accepted.
+ if (!frame->software_frame_data) {
+ DLOG(ERROR) << "Received unexpected frame type.";
+ RecordAction(UserMetricsAction(
+ "BadMessageTerminate_UnexpectedFrameType"));
+ render_widget_host_->GetProcess()->ReceivedBadMessage();
+ return;
+ }
+
+ GotSoftwareFrame();
+ if (!software_frame_manager_->SwapToNewFrame(
+ output_surface_id,
+ frame->software_frame_data.get(),
+ frame->metadata.device_scale_factor,
+ render_widget_host_->GetProcess()->GetHandle())) {
+ render_widget_host_->GetProcess()->ReceivedBadMessage();
+ return;
+ }
+ software_frame_manager_->SwapToNewFrameComplete(
+ !render_widget_host_->is_hidden());
+
+ [cocoa_view_ setNeedsDisplay:YES];
+}
+
void RenderWidgetHostViewMac::OnAcceleratedCompositingStateChange() {
}
@@ -1741,6 +1780,19 @@ bool RenderWidgetHostViewMac::Send(IPC::Message* message) {
return false;
}
+void RenderWidgetHostViewMac::SoftwareFrameWasFreed(
+ uint32 output_surface_id, unsigned frame_id) {
+ cc::CompositorFrameAck ack;
+ ack.last_software_frame_id = frame_id;
+ RenderWidgetHostImpl::SendReclaimCompositorResources(
+ render_widget_host_->GetRoutingID(),
+ output_surface_id,
+ render_widget_host_->GetProcess()->GetID(),
+ ack);
+}
+
+void RenderWidgetHostViewMac::ReleaseReferencesToSoftwareFrame() {
+}
void RenderWidgetHostViewMac::ShutdownHost() {
weak_factory_.InvalidateWeakPtrs();
@@ -1764,6 +1816,7 @@ void RenderWidgetHostViewMac::GotAcceleratedFrame() {
// Delete software backingstore.
BackingStoreManager::RemoveBackingStore(render_widget_host_);
+ software_frame_manager_->DiscardCurrentFrame();
}
}
@@ -2718,29 +2771,62 @@ void RenderWidgetHostViewMac::FrameSwapped() {
- (void)drawBackingStore:(BackingStoreMac*)backingStore
dirtyRect:(CGRect)dirtyRect
inContext:(CGContextRef)context {
- if (backingStore) {
+ content::SoftwareFrameManager* software_frame_manager =
+ renderWidgetHostView_->software_frame_manager_.get();
+ // There should never be both a legacy software and software composited
+ // frame.
+ DCHECK(!backingStore || !software_frame_manager->HasCurrentFrame());
+
+ if (backingStore || software_frame_manager->HasCurrentFrame()) {
// Note: All coordinates are in view units, not pixels.
- gfx::Rect bitmapRect(0, 0,
- backingStore->size().width(),
- backingStore->size().height());
+ gfx::Rect bitmapRect(
+ software_frame_manager->HasCurrentFrame() ?
+ software_frame_manager->GetCurrentFrameSizeInDIP() :
+ backingStore->size());
// Specify the proper y offset to ensure that the view is rooted to the
// upper left corner. This can be negative, if the window was resized
// smaller and the renderer hasn't yet repainted.
- int yOffset = NSHeight([self bounds]) - backingStore->size().height();
+ int yOffset = NSHeight([self bounds]) - bitmapRect.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()) {
+ if (software_frame_manager->HasCurrentFrame()) {
+ // If a software compositor framebuffer is present, draw using that.
+ gfx::Size sizeInPixels =
+ software_frame_manager->GetCurrentFrameSizeInPixels();
+ base::ScopedCFTypeRef<CGDataProviderRef> dataProvider(
+ CGDataProviderCreateWithData(
+ NULL,
+ software_frame_manager->GetCurrentFramePixels(),
+ 4 * sizeInPixels.width() * sizeInPixels.height(),
+ NULL));
+ base::ScopedCFTypeRef<CGImageRef> image(
+ CGImageCreate(
+ sizeInPixels.width(),
+ sizeInPixels.height(),
+ 8,
+ 32,
+ 4 * sizeInPixels.width(),
+ base::mac::GetSystemColorSpace(),
+ kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host,
+ dataProvider,
+ NULL,
+ false,
+ kCGRenderingIntentDefault));
+ CGRect imageRect = bitmapRect.ToCGRect();
+ imageRect.origin.y = yOffset;
+ CGContextDrawImage(context, imageRect, image);
+ } else if (backingStore->cg_layer()) {
+ // If we have a CGLayer, draw that into the window
// TODO: add clipping to dirtyRect if it improves drawing performance.
CGContextDrawLayerAtPoint(context, CGPointMake(0.0, yOffset),
backingStore->cg_layer());
} else {
- // if we haven't created a layer yet, draw the cached bitmap into
+ // 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.
base::ScopedCFTypeRef<CGImageRef> image(
« no previous file with comments | « content/browser/renderer_host/render_widget_host_view_mac.h ('k') | content/browser/renderer_host/software_frame_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698