summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authorccameron@chromium.org <ccameron@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-13 08:59:30 +0000
committerccameron@chromium.org <ccameron@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-13 08:59:30 +0000
commitd0c709d668f0a935f933c3a11fc55041261e443b (patch)
tree6d16f7c51d42da4bae6999f2a2c2722263e75a30 /content
parent77d83548dd628eb33a86ba4057399d75e8aa2266 (diff)
downloadchromium_src-d0c709d668f0a935f933c3a11fc55041261e443b.zip
chromium_src-d0c709d668f0a935f933c3a11fc55041261e443b.tar.gz
chromium_src-d0c709d668f0a935f933c3a11fc55041261e443b.tar.bz2
Work before enabling software compositing on Mac
Implement RenderWidgetHostViewMac::CopyFromCompositingSurface for the software compositing path and disable copying to video frames and frame subscription (this path needs to be functional, but not particularly performant). Fix a bug where RenderWidgetHostViewMac::SoftwareFrameWasFreed would reach in to a destroyed RenderWidgetHostImpl. Fix a bug where RenderWidgetHostViewMac::software_latency_info_ was not updated in RenderWidgetHostViewMac::OnSwapCompositorFrame. Fix a bug where the ack for a software frame is sent immediately, instead of when the frame is actually drawn. BUG=286038 R=hclam@chromium.org Review URL: https://codereview.chromium.org/113603002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@240558 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r--content/browser/renderer_host/render_widget_host_view_browsertest.cc14
-rw-r--r--content/browser/renderer_host/render_widget_host_view_mac.h4
-rw-r--r--content/browser/renderer_host/render_widget_host_view_mac.mm85
-rw-r--r--content/browser/renderer_host/software_frame_manager.cc25
-rw-r--r--content/browser/renderer_host/software_frame_manager.h4
5 files changed, 106 insertions, 26 deletions
diff --git a/content/browser/renderer_host/render_widget_host_view_browsertest.cc b/content/browser/renderer_host/render_widget_host_view_browsertest.cc
index c6cb8d6..60172d3 100644
--- a/content/browser/renderer_host/render_widget_host_view_browsertest.cc
+++ b/content/browser/renderer_host/render_widget_host_view_browsertest.cc
@@ -648,6 +648,20 @@ class CompositingRenderWidgetHostViewBrowserTestTabCapture
return;
RenderWidgetHostViewPort* rwhvp = GetRenderWidgetHostViewPort();
+ if (video_frame && !rwhvp->CanCopyToVideoFrame()) {
+ // This should only happen on Mac when using the software compositor.
+ // Otherwise, raise an error. This can be removed when Mac is moved to a
+ // browser compositor.
+ // http://crbug.com/314190
+#if defined(OS_MACOSX)
+ if (!content::GpuDataManager::GetInstance()->GpuAccessAllowed(NULL)) {
+ LOG(WARNING) << ("Blindly passing this test because copying to "
+ "video frames is not supported on this platform.");
+ return;
+ }
+#endif
+ NOTREACHED();
+ }
// The page is loaded in the renderer, wait for a new frame to arrive.
uint32 frame = rwhvp->RendererFrameNumber();
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.h b/content/browser/renderer_host/render_widget_host_view_mac.h
index 00c4282..b6825b0 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.h
+++ b/content/browser/renderer_host/render_widget_host_view_mac.h
@@ -435,6 +435,10 @@ class RenderWidgetHostViewMac : public RenderWidgetHostViewBase,
// This holds the current software compositing framebuffer, if any.
scoped_ptr<SoftwareFrameManager> software_frame_manager_;
+ // This is set when a new software frame is received and un-set when the
+ // frame's ack is sent back to the renderer.
+ bool software_frame_needs_to_send_ack_;
+
// Whether to allow overlapping views.
bool allow_overlapping_views_;
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 9b5de7f..9e1c6fd 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -412,6 +412,7 @@ RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget)
last_frame_was_accelerated_(false),
text_input_type_(ui::TEXT_INPUT_TYPE_NONE),
can_compose_inline_(true),
+ software_frame_needs_to_send_ack_(false),
allow_overlapping_views_(false),
use_core_animation_(false),
is_loading_(false),
@@ -845,6 +846,7 @@ bool RenderWidgetHostViewMac::HasFocus() const {
bool RenderWidgetHostViewMac::IsSurfaceAvailableForCopy() const {
return !!render_widget_host_->GetBackingStore(false) ||
+ software_frame_manager_->HasCurrentFrame() ||
(compositing_iosurface_ && compositing_iosurface_->HasIOSurface());
}
@@ -1144,19 +1146,51 @@ void RenderWidgetHostViewMac::CopyFromCompositingSurface(
const base::Callback<void(bool, const SkBitmap&)>& callback) {
base::ScopedClosureRunner scoped_callback_runner(
base::Bind(callback, false, SkBitmap()));
- if (!compositing_iosurface_ ||
- !compositing_iosurface_->HasIOSurface())
- return;
-
float scale = ScaleFactor(cocoa_view_);
gfx::Size dst_pixel_size = gfx::ToFlooredSize(
gfx::ScaleSize(dst_size, scale));
+ if (compositing_iosurface_ && compositing_iosurface_->HasIOSurface()) {
+ ignore_result(scoped_callback_runner.Release());
+ compositing_iosurface_->CopyTo(GetScaledOpenGLPixelRect(src_subrect),
+ dst_pixel_size,
+ callback);
+ } else if (software_frame_manager_->HasCurrentFrame()) {
+ gfx::Rect src_pixel_rect = gfx::ToEnclosingRect(gfx::ScaleRect(
+ src_subrect,
+ software_frame_manager_->GetCurrentFrameDeviceScaleFactor()));
+ SkBitmap source_bitmap;
+ source_bitmap.setConfig(
+ SkBitmap::kARGB_8888_Config,
+ software_frame_manager_->GetCurrentFrameSizeInPixels().width(),
+ software_frame_manager_->GetCurrentFrameSizeInPixels().height(),
+ 0,
+ kOpaque_SkAlphaType);
+ source_bitmap.setPixels(software_frame_manager_->GetCurrentFramePixels());
+
+ SkBitmap target_bitmap;
+ target_bitmap.setConfig(
+ SkBitmap::kARGB_8888_Config,
+ dst_pixel_size.width(),
+ dst_pixel_size.height(),
+ 0,
+ kOpaque_SkAlphaType);
+ if (!target_bitmap.allocPixels())
+ return;
- ignore_result(scoped_callback_runner.Release());
+ SkCanvas target_canvas(target_bitmap);
+ SkRect src_pixel_skrect = SkRect::MakeXYWH(
+ src_pixel_rect.x(), src_pixel_rect.y(),
+ src_pixel_rect.width(), src_pixel_rect.height());
+ target_canvas.drawBitmapRectToRect(
+ source_bitmap,
+ &src_pixel_skrect,
+ SkRect::MakeXYWH(0, 0, dst_pixel_size.width(), dst_pixel_size.height()),
+ NULL,
+ SkCanvas::kNone_DrawBitmapRectFlag);
- compositing_iosurface_->CopyTo(GetScaledOpenGLPixelRect(src_subrect),
- dst_pixel_size,
- callback);
+ ignore_result(scoped_callback_runner.Release());
+ callback.Run(true, target_bitmap);
+ }
}
void RenderWidgetHostViewMac::CopyFromCompositingSurfaceToVideoFrame(
@@ -1192,13 +1226,14 @@ void RenderWidgetHostViewMac::CopyFromCompositingSurfaceToVideoFrame(
bool RenderWidgetHostViewMac::CanCopyToVideoFrame() const {
return (!render_widget_host_->GetBackingStore(false) &&
+ !software_frame_manager_->HasCurrentFrame() &&
render_widget_host_->is_accelerated_compositing_active() &&
compositing_iosurface_ &&
compositing_iosurface_->HasIOSurface());
}
bool RenderWidgetHostViewMac::CanSubscribeFrame() const {
- return true;
+ return !software_frame_manager_->HasCurrentFrame();
}
void RenderWidgetHostViewMac::BeginFrameSubscription(
@@ -1729,7 +1764,10 @@ void RenderWidgetHostViewMac::OnSwapCompositorFrame(
return;
}
- GotSoftwareFrame();
+ // Ack any swaps that didn't make it to the display.
+ if (software_frame_needs_to_send_ack_)
+ FrameSwapped();
+
if (!software_frame_manager_->SwapToNewFrame(
output_surface_id,
frame->software_frame_data.get(),
@@ -1738,15 +1776,10 @@ void RenderWidgetHostViewMac::OnSwapCompositorFrame(
render_widget_host_->GetProcess()->ReceivedBadMessage();
return;
}
- software_frame_manager_->SwapToNewFrameComplete(
- !render_widget_host_->is_hidden());
- cc::CompositorFrameAck ack;
- RenderWidgetHostImpl::SendSwapCompositorFrameAck(
- render_widget_host_->GetRoutingID(),
- output_surface_id,
- render_widget_host_->GetProcess()->GetID(),
- ack);
+ GotSoftwareFrame();
+ software_latency_info_.MergeWith(frame->metadata.latency_info);
+ software_frame_needs_to_send_ack_ = true;
[cocoa_view_ setNeedsDisplay:YES];
}
@@ -1837,6 +1870,8 @@ bool RenderWidgetHostViewMac::Send(IPC::Message* message) {
void RenderWidgetHostViewMac::SoftwareFrameWasFreed(
uint32 output_surface_id, unsigned frame_id) {
+ if (!render_widget_host_)
+ return;
cc::CompositorFrameAck ack;
ack.last_software_frame_id = frame_id;
RenderWidgetHostImpl::SendReclaimCompositorResources(
@@ -2002,6 +2037,20 @@ gfx::Rect RenderWidgetHostViewMac::GetScaledOpenGLPixelRect(
}
void RenderWidgetHostViewMac::FrameSwapped() {
+ if (software_frame_needs_to_send_ack_ &&
+ software_frame_manager_->HasCurrentFrame()) {
+ software_frame_manager_->SwapToNewFrameComplete(
+ !render_widget_host_->is_hidden());
+
+ cc::CompositorFrameAck ack;
+ RenderWidgetHostImpl::SendSwapCompositorFrameAck(
+ render_widget_host_->GetRoutingID(),
+ software_frame_manager_->GetCurrentFrameOutputSurfaceId(),
+ render_widget_host_->GetProcess()->GetID(),
+ ack);
+ software_frame_needs_to_send_ack_ = false;
+ }
+
software_latency_info_.AddLatencyNumber(
ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT, 0, 0);
render_widget_host_->FrameSwapped(software_latency_info_);
diff --git a/content/browser/renderer_host/software_frame_manager.cc b/content/browser/renderer_host/software_frame_manager.cc
index f9cc1d8..147c21e 100644
--- a/content/browser/renderer_host/software_frame_manager.cc
+++ b/content/browser/renderer_host/software_frame_manager.cc
@@ -32,7 +32,7 @@ class CONTENT_EXPORT SoftwareFrame : public base::RefCounted<SoftwareFrame> {
base::WeakPtr<SoftwareFrameManagerClient> frame_manager_client,
uint32 output_surface_id,
unsigned frame_id,
- gfx::Size frame_size_dip,
+ float frame_device_scale_factor,
gfx::Size frame_size_pixels,
scoped_ptr<base::SharedMemory> shared_memory);
~SoftwareFrame();
@@ -40,7 +40,7 @@ class CONTENT_EXPORT SoftwareFrame : public base::RefCounted<SoftwareFrame> {
base::WeakPtr<SoftwareFrameManagerClient> frame_manager_client_;
const uint32 output_surface_id_;
const unsigned frame_id_;
- const gfx::Size frame_size_dip_;
+ float frame_device_scale_factor_;
const gfx::Size frame_size_pixels_;
scoped_ptr<base::SharedMemory> shared_memory_;
@@ -51,13 +51,13 @@ SoftwareFrame::SoftwareFrame(
base::WeakPtr<SoftwareFrameManagerClient> frame_manager_client,
uint32 output_surface_id,
unsigned frame_id,
- gfx::Size frame_size_dip,
+ float frame_device_scale_factor,
gfx::Size frame_size_pixels,
scoped_ptr<base::SharedMemory> shared_memory)
: frame_manager_client_(frame_manager_client),
output_surface_id_(output_surface_id),
frame_id_(frame_id),
- frame_size_dip_(frame_size_dip),
+ frame_device_scale_factor_(frame_device_scale_factor),
frame_size_pixels_(frame_size_pixels),
shared_memory_(shared_memory.Pass()) {}
@@ -125,7 +125,7 @@ bool SoftwareFrameManager::SwapToNewFrame(
client_,
output_surface_id,
frame_data->id,
- ConvertSizeToDIP(frame_device_scale_factor, frame_data->size),
+ frame_device_scale_factor,
frame_data->size,
shared_memory.Pass()));
current_frame_.swap(next_frame);
@@ -154,6 +154,11 @@ void SoftwareFrameManager::SetVisibility(bool visible) {
}
}
+uint32 SoftwareFrameManager::GetCurrentFrameOutputSurfaceId() const {
+ DCHECK(HasCurrentFrame());
+ return current_frame_->output_surface_id_;
+}
+
void SoftwareFrameManager::GetCurrentFrameMailbox(
cc::TextureMailbox* mailbox,
scoped_ptr<cc::SingleReleaseCallback>* callback) {
@@ -164,13 +169,18 @@ void SoftwareFrameManager::GetCurrentFrameMailbox(
base::Bind(ReleaseMailbox, current_frame_));
}
-const void* SoftwareFrameManager::GetCurrentFramePixels() const {
+void* SoftwareFrameManager::GetCurrentFramePixels() const {
DCHECK(HasCurrentFrame());
DCHECK(base::SharedMemory::IsHandleValid(
current_frame_->shared_memory_->handle()));
return current_frame_->shared_memory_->memory();
}
+float SoftwareFrameManager::GetCurrentFrameDeviceScaleFactor() const {
+ DCHECK(HasCurrentFrame());
+ return current_frame_->frame_device_scale_factor_;
+}
+
gfx::Size SoftwareFrameManager::GetCurrentFrameSizeInPixels() const {
DCHECK(HasCurrentFrame());
return current_frame_->frame_size_pixels_;
@@ -178,7 +188,8 @@ gfx::Size SoftwareFrameManager::GetCurrentFrameSizeInPixels() const {
gfx::Size SoftwareFrameManager::GetCurrentFrameSizeInDIP() const {
DCHECK(HasCurrentFrame());
- return current_frame_->frame_size_dip_;
+ return ConvertSizeToDIP(current_frame_->frame_device_scale_factor_,
+ current_frame_->frame_size_pixels_);
}
void SoftwareFrameManager::EvictCurrentFrame() {
diff --git a/content/browser/renderer_host/software_frame_manager.h b/content/browser/renderer_host/software_frame_manager.h
index 503a40d..6d19afd 100644
--- a/content/browser/renderer_host/software_frame_manager.h
+++ b/content/browser/renderer_host/software_frame_manager.h
@@ -52,10 +52,12 @@ class CONTENT_EXPORT SoftwareFrameManager : public RendererFrameManagerClient {
void SetVisibility(bool visible);
bool HasCurrentFrame() const;
void DiscardCurrentFrame();
+ uint32 GetCurrentFrameOutputSurfaceId() const;
void GetCurrentFrameMailbox(
cc::TextureMailbox* mailbox,
scoped_ptr<cc::SingleReleaseCallback>* callback);
- const void* GetCurrentFramePixels() const;
+ void* GetCurrentFramePixels() const;
+ float GetCurrentFrameDeviceScaleFactor() const;
gfx::Size GetCurrentFrameSizeInPixels() const;
gfx::Size GetCurrentFrameSizeInDIP() const;