Chromium Code Reviews| Index: content/browser/renderer_host/render_widget_host_view_aura.cc |
| diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc |
| index 30d1fb79d8b6b9d09a9add8950f41a2189526e55..0550fcc9a7b86495147dbd789af8377f2002c85c 100644 |
| --- a/content/browser/renderer_host/render_widget_host_view_aura.cc |
| +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc |
| @@ -13,6 +13,7 @@ |
| #include "base/string_number_conversions.h" |
| #include "cc/output/compositor_frame.h" |
| #include "cc/output/compositor_frame_ack.h" |
| +#include "cc/resources/texture_mailbox.h" |
| #include "content/browser/accessibility/browser_accessibility_manager.h" |
| #include "content/browser/accessibility/browser_accessibility_state_impl.h" |
| #include "content/browser/renderer_host/backing_store_aura.h" |
| @@ -344,6 +345,13 @@ void AcknowledgeBufferForGpu( |
| route_id, gpu_host_id, ack); |
| } |
| +void ReleaseMailbox(scoped_ptr<base::SharedMemory> shared_memory, |
| + base::Callback<void()> callback, |
| + unsigned sync_point, bool lost_resource) { |
| + callback.Run(); |
| + shared_memory.reset(NULL); |
|
piman
2013/06/07 01:26:28
nit: you actually don't need this, it'll go away b
slavi
2013/06/07 21:49:21
I knew that. I thought leaving it makes the code c
|
| +} |
| + |
| } // namespace |
| // We need to watch for mouse events outside a Web Popup or its parent |
| @@ -941,7 +949,9 @@ bool RenderWidgetHostViewAura::HasFocus() const { |
| } |
| bool RenderWidgetHostViewAura::IsSurfaceAvailableForCopy() const { |
| - return current_surface_ || current_dib_ || !!host_->GetBackingStore(false); |
| + return current_surface_ || |
| + current_software_frame_.IsValid() || |
| + !!host_->GetBackingStore(false); |
| } |
| void RenderWidgetHostViewAura::Show() { |
| @@ -1285,6 +1295,7 @@ void RenderWidgetHostViewAura::CopyFromCompositingSurfaceToVideoFrame( |
| } |
| bool RenderWidgetHostViewAura::CanCopyToVideoFrame() const { |
| + // TODO(skaslev): Implement this path for s/w compositing. |
| return current_surface_ != NULL && host_->is_accelerated_compositing_active(); |
| } |
| @@ -1347,17 +1358,20 @@ void RenderWidgetHostViewAura::UpdateExternalTexture() { |
| bool is_compositing_active = host_->is_accelerated_compositing_active(); |
| if (is_compositing_active && current_surface_) { |
| - window_->SetExternalTexture(current_surface_.get()); |
| + window_->layer()->SetExternalTexture(current_surface_.get()); |
| current_frame_size_ = ConvertSizeToDIP( |
| current_surface_->device_scale_factor(), current_surface_->size()); |
| CheckResizeLock(); |
| - } else if (is_compositing_active && current_dib_) { |
| - window_->SetExternalTexture(NULL); |
| - current_frame_size_ = ConvertSizeToDIP(last_swapped_surface_scale_factor_, |
| - last_swapped_surface_size_); |
| + } else if (is_compositing_active && |
| + current_software_frame_.IsSharedMemory()) { |
| + window_->layer()->SetTextureMailbox(current_software_frame_, |
| + last_swapped_surface_scale_factor_); |
| + current_frame_size_ = ConvertSizeToDIP( |
| + last_swapped_surface_scale_factor_, |
| + current_software_frame_.shared_memory_size()); |
| CheckResizeLock(); |
| } else { |
| - window_->SetExternalTexture(NULL); |
| + window_->layer()->SetExternalTexture(NULL); |
| resize_lock_.reset(); |
| host_->WasResized(); |
| } |
| @@ -1520,62 +1534,73 @@ void RenderWidgetHostViewAura::SwapSoftwareFrame( |
| scoped_ptr<cc::SoftwareFrameData> frame_data, |
| float frame_device_scale_factor, |
| const ui::LatencyInfo& latency_info) { |
| + ui::Compositor* compositor = GetCompositor(); |
| + if (!compositor) { |
|
piman
2013/06/07 01:26:28
I believe I mentioned that earlier. GetCompositor
slavi
2013/06/07 21:49:21
Done.
|
| + SendSoftwareFrameAck(frame_data->id); |
| + return; |
| + } |
| + |
| const gfx::Size& frame_size = frame_data->size; |
| const gfx::Rect& damage_rect = frame_data->damage_rect; |
| - const TransportDIB::Id& dib_id = frame_data->dib_id; |
| - scoped_ptr<TransportDIB> dib(host_->GetProcess()->MapTransportDIB(dib_id)); |
| + gfx::Size frame_size_in_dip = |
| + ConvertSizeToDIP(frame_device_scale_factor, frame_size); |
| + if (ShouldSkipFrame(frame_size_in_dip)) { |
| + SendSoftwareFrameAck(frame_data->id); |
| + return; |
| + } |
| - // Validate the received DIB. |
| - size_t expected_size = 4 * frame_size.GetArea(); |
| - if (!dib || dib->size() < expected_size) { |
| + base::SharedMemoryHandle handle = frame_data->handle; |
| +#ifdef OS_WIN |
| + BOOL success = ::DuplicateHandle( |
| + host_->GetProcess()->GetHandle(), frame_data->handle, |
| + ::GetCurrentProcess(), &handle, |
| + 0, TRUE, DUPLICATE_SAME_ACCESS); |
| + if (!success) { |
| + host_->GetProcess()->ReceivedBadMessage(); |
| + return; |
| + } |
| +#endif |
| + const size_t expected_size = 4 * frame_size.GetArea(); |
| + scoped_ptr<base::SharedMemory> shared_memory( |
| + new base::SharedMemory(handle, false)); |
| + if (!shared_memory->Map(expected_size)) { |
| host_->GetProcess()->ReceivedBadMessage(); |
| return; |
| } |
| if (last_swapped_surface_size_ != frame_size) { |
| DLOG_IF(ERROR, damage_rect != gfx::Rect(frame_size)) |
| - << "Expected full damage rect"; |
| + << "Expected full damage rect"; |
| } |
| - |
| - TransportDIB::Id last_dib_id = current_dib_id_; |
| - current_dib_.reset(dib.release()); |
| - current_dib_id_ = dib_id; |
| last_swapped_surface_size_ = frame_size; |
| last_swapped_surface_scale_factor_ = frame_device_scale_factor; |
| - ui::Compositor* compositor = GetCompositor(); |
| - if (!compositor) { |
| - SendSoftwareFrameAck(last_dib_id); |
| - return; |
| - } |
| - |
| - gfx::Size frame_size_in_dip = |
| - ConvertSizeToDIP(frame_device_scale_factor, frame_size); |
| - if (ShouldSkipFrame(frame_size_in_dip)) { |
| - can_lock_compositor_ = NO_PENDING_COMMIT; |
| - SendSoftwareFrameAck(last_dib_id); |
| - } else { |
| - AddOnCommitCallbackAndDisableLocks( |
| - base::Bind(&RenderWidgetHostViewAura::SendSoftwareFrameAck, |
| - AsWeakPtr(), last_dib_id)); |
| - } |
| - |
| + base::SharedMemory* shared_memory_raw_ptr = shared_memory.get(); |
| + cc::TextureMailbox::ReleaseCallback callback = |
| + base::Bind(ReleaseMailbox, Passed(shared_memory.Pass()), |
|
piman
2013/06/07 01:26:28
nit: Passed(shared_memory) should work.
slavi
2013/06/07 21:49:21
It doesn't.
piman
2013/06/07 23:29:59
ok, Passed(&shared_memory).
|
| + base::Bind(&RenderWidgetHostViewAura::SendSoftwareFrameAck, |
| + AsWeakPtr(), frame_data->id)); |
| + current_software_frame_ = |
| + cc::TextureMailbox(shared_memory_raw_ptr, frame_size, callback); |
| + DCHECK(current_software_frame_.IsSharedMemory()); |
| current_frame_size_ = frame_size_in_dip; |
| - CheckResizeLock(); |
| + |
| released_front_lock_ = NULL; |
| - window_->SetExternalTexture(NULL); |
| + CheckResizeLock(); |
| + window_->layer()->SetTextureMailbox(current_software_frame_, |
| + frame_device_scale_factor); |
| window_->SchedulePaintInRect( |
| ConvertRectToDIP(frame_device_scale_factor, damage_rect)); |
| - compositor->SetLatencyInfo(latency_info); |
| + compositor->SetLatencyInfo(latency_info); |
| if (paint_observer_) |
| paint_observer_->OnUpdateCompositorContent(); |
| } |
| void RenderWidgetHostViewAura::SendSoftwareFrameAck( |
| - const TransportDIB::Id& id) { |
| + unsigned software_frame_id) { |
| cc::CompositorFrameAck ack; |
| - ack.last_dib_id = id; |
| + ack.last_software_frame_id = software_frame_id; |
| RenderWidgetHostImpl::SendSwapCompositorFrameAck( |
| host_->GetRoutingID(), host_->GetProcess()->GetID(), ack); |
| } |
| @@ -2192,36 +2217,8 @@ void RenderWidgetHostViewAura::OnCaptureLost() { |
| } |
| void RenderWidgetHostViewAura::OnPaint(gfx::Canvas* canvas) { |
| - bool is_compositing_active = host_->is_accelerated_compositing_active(); |
| bool has_backing_store = !!host_->GetBackingStore(false); |
| - if (is_compositing_active && current_dib_) { |
| - const gfx::Size window_size = window_->bounds().size(); |
| - const gfx::Size& frame_size = last_swapped_surface_size_; |
| - |
| - SkBitmap bitmap; |
| - bitmap.setConfig(SkBitmap::kARGB_8888_Config, |
| - frame_size.width(), |
| - frame_size.height()); |
| - bitmap.setPixels(current_dib_->memory()); |
| - |
| - SkCanvas* sk_canvas = canvas->sk_canvas(); |
| - sk_canvas->drawBitmap(bitmap, 0, 0); |
| - |
| - if (frame_size != window_size) { |
| - SkRegion region; |
| - region.op(0, 0, window_size.width(), window_size.height(), |
| - SkRegion::kUnion_Op); |
| - region.op(0, 0, frame_size.width(), frame_size.height(), |
| - SkRegion::kDifference_Op); |
| - SkPaint paint; |
| - paint.setColor(SK_ColorWHITE); |
| - for (SkRegion::Iterator it(region); !it.done(); it.next()) |
| - sk_canvas->drawIRect(it.rect(), paint); |
| - } |
| - |
| - if (paint_observer_) |
| - paint_observer_->OnPaintComplete(); |
| - } else if (!is_compositing_active && has_backing_store) { |
| + if (has_backing_store) { |
| paint_canvas_ = canvas; |
| BackingStoreAura* backing_store = static_cast<BackingStoreAura*>( |
| host_->GetBackingStore(true)); |