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 a5daece4afeb883793413f60f38ba46fec151e22..4c7759946b9d2b070438cc8e1d0fa945c7c47e65 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,12 @@ 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(); |
+} |
+ |
} // namespace |
// We need to watch for mouse events outside a Web Popup or its parent |
@@ -941,7 +948,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 +1294,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 +1357,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(); |
} |
@@ -1522,60 +1535,67 @@ void RenderWidgetHostViewAura::SwapSoftwareFrame( |
const ui::LatencyInfo& latency_info) { |
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), |
+ 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); |
+ ui::Compositor* compositor = GetCompositor(); |
+ if (compositor) |
+ 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 +2212,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)); |