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

Unified Diff: content/browser/renderer_host/software_framebuffer.cc

Issue 25942002: Make software compositing work on Mac. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Touch-ups 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/software_framebuffer.cc
diff --git a/content/browser/renderer_host/software_framebuffer.cc b/content/browser/renderer_host/software_framebuffer.cc
new file mode 100644
index 0000000000000000000000000000000000000000..3101da74b49ef79880bac16d4801cfbff331a0a2
--- /dev/null
+++ b/content/browser/renderer_host/software_framebuffer.cc
@@ -0,0 +1,188 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "software_framebuffer.h"
+
+#include "cc/output/compositor_frame_ack.h"
+#include "content/browser/renderer_host/dip_util.h"
+#include "content/browser/renderer_host/frame_memory_manager.h"
+#include "content/public/browser/render_process_host.h"
+
+namespace content {
+
+class MemoryHolder : public base::RefCounted<MemoryHolder> {
+ public:
+ MemoryHolder(scoped_ptr<base::SharedMemory> shared_memory,
+ gfx::Size frame_size,
+ float frame_scale_factor,
+ base::Callback<void()> callback)
+ : shared_memory_(shared_memory.Pass()),
+ frame_size_(frame_size),
+ frame_scale_factor_(frame_scale_factor),
+ callback_(callback) {}
+
+ void GetMailbox(cc::TextureMailbox* mailbox,
+ scoped_ptr<cc::SingleReleaseCallback>* release_callback) {
+ *mailbox = cc::TextureMailbox(shared_memory_.get(), frame_size_);
+ *release_callback = cc::SingleReleaseCallback::Create(
+ base::Bind(ReleaseMailbox, make_scoped_refptr(this)));
+ }
+ const gfx::Size& GetSizeInPixels() const { return frame_size_; }
+ float GetScaleFactor() const { return frame_scale_factor_; }
+ const void* GetPixels() const { return shared_memory_->memory(); }
+
+ private:
+ friend class base::RefCounted<MemoryHolder>;
+ ~MemoryHolder() { callback_.Run(); }
+
+ static void ReleaseMailbox(scoped_refptr<MemoryHolder> holder,
+ unsigned sync_point,
+ bool lost_resource) {}
+
+ scoped_ptr<base::SharedMemory> shared_memory_;
+ gfx::Size frame_size_;
+ float frame_scale_factor_;
+ base::Callback<void()> callback_;
+};
+
+SoftwareFramebuffer::SoftwareFramebuffer(
+ SoftwareFramebufferClient* client,
+ RenderWidgetHostImpl* render_widget_host_impl)
+ : client_(client), render_widget_host_impl_(render_widget_host_impl) {}
+
+SoftwareFramebuffer::~SoftwareFramebuffer() {
+ client_ = NULL;
+ render_widget_host_impl_ = NULL;
+ DiscardCurrentFrame();
+}
+
+void SoftwareFramebuffer::WasShown() {
+ if (framebuffer_holder_)
+ FrameMemoryManager::GetInstance()->SetFrameVisibility(this, true);
+}
+
+void SoftwareFramebuffer::WasHidden() {
+ if (framebuffer_holder_)
+ FrameMemoryManager::GetInstance()->SetFrameVisibility(this, false);
+}
+
+void SoftwareFramebuffer::DiscardCurrentFrame() {
+ FrameMemoryManager::GetInstance()->RemoveFrame(this);
+ framebuffer_holder_ = NULL;
+}
+
+void SoftwareFramebuffer::GetCurrentFrameMailbox(
+ cc::TextureMailbox* mailbox,
+ scoped_ptr<cc::SingleReleaseCallback>* release_callback) const {
+ DCHECK(framebuffer_holder_);
+ return framebuffer_holder_->GetMailbox(mailbox,
+ release_callback);
+}
+
+gfx::Size SoftwareFramebuffer::GetCurrentFrameSizeInPixels() const {
+ DCHECK(framebuffer_holder_);
+ return framebuffer_holder_->GetSizeInPixels();
+}
+
+gfx::Size SoftwareFramebuffer::GetCurrentFrameSizeInDIP() const {
+ DCHECK(framebuffer_holder_);
+ return ConvertSizeToDIP(framebuffer_holder_->GetScaleFactor(),
+ framebuffer_holder_->GetSizeInPixels());
+}
+
+const void* SoftwareFramebuffer::GetCurrentFramePixels() const {
+ DCHECK(framebuffer_holder_);
+ return framebuffer_holder_->GetPixels();
+}
+
+void SoftwareFramebuffer::SwapToNewFrame(
+ uint32 output_surface_id,
+ const cc::SoftwareFrameData* frame_data,
+ float frame_scale_factor) {
+ const gfx::Size& frame_size = frame_data->size;
+ const size_t size_in_bytes = 4 * frame_size.GetArea();
+
+#ifdef OS_WIN
+ scoped_ptr<base::SharedMemory> shared_memory(
+ new base::SharedMemory(frame_data->handle, true,
+ render_widget_host_impl_->GetProcess()->GetHandle()));
+#else
+ scoped_ptr<base::SharedMemory> shared_memory(
+ new base::SharedMemory(frame_data->handle, true));
+#endif
+
+ if (!shared_memory->Map(size_in_bytes)) {
+ render_widget_host_impl_->GetProcess()->ReceivedBadMessage();
+ framebuffer_holder_ = NULL;
+ return;
+ }
+
+ scoped_refptr<MemoryHolder> holder(new MemoryHolder(
+ shared_memory.Pass(),
+ frame_size,
+ frame_scale_factor,
+ base::Bind(&SoftwareFramebuffer::ReleaseSoftwareFrame,
+ AsWeakPtr(),
+ output_surface_id,
+ frame_data->id)));
+ framebuffer_holder_.swap(holder);
+
+ FrameMemoryManager::GetInstance()->AddFrame(
+ this, !render_widget_host_impl_->is_hidden());
+}
+
+void SoftwareFramebuffer::SendSoftwareFrameAck(uint32 output_surface_id) {
+ unsigned software_frame_id = 0;
+ if (!released_software_frames_.empty()) {
+ unsigned released_output_surface_id =
+ released_software_frames_.back().output_surface_id;
+ if (released_output_surface_id == output_surface_id) {
+ software_frame_id = released_software_frames_.back().frame_id;
+ released_software_frames_.pop_back();
+ }
+ }
+
+ cc::CompositorFrameAck ack;
+ ack.last_software_frame_id = software_frame_id;
+ if (render_widget_host_impl_) {
+ RenderWidgetHostImpl::SendSwapCompositorFrameAck(
piman 2013/10/08 02:58:38 I would really prefer if the message sending logic
ccameron 2013/10/22 07:15:55 I did essentially this in the new version. The cal
+ render_widget_host_impl_->GetRoutingID(), output_surface_id,
+ render_widget_host_impl_->GetProcess()->GetID(), ack);
+ }
+ SendReclaimSoftwareFrames();
+}
+
+void SoftwareFramebuffer::SendReclaimSoftwareFrames() {
+ while (!released_software_frames_.empty()) {
+ cc::CompositorFrameAck ack;
+ ack.last_software_frame_id = released_software_frames_.back().frame_id;
+ if (render_widget_host_impl_) {
+ RenderWidgetHostImpl::SendReclaimCompositorResources(
+ render_widget_host_impl_->GetRoutingID(),
+ released_software_frames_.back().output_surface_id,
+ render_widget_host_impl_->GetProcess()->GetID(),
+ ack);
+ }
+ released_software_frames_.pop_back();
+ }
+}
+
+void SoftwareFramebuffer::ReleaseSoftwareFrame(
+ uint32 output_surface_id,
+ unsigned software_frame_id) {
+ SendReclaimSoftwareFrames();
+ released_software_frames_.push_back(
+ ReleasedFrameInfo(output_surface_id, software_frame_id));
+}
+
+void SoftwareFramebuffer::ReleaseCurrentFrame() {
+ DCHECK(framebuffer_holder_);
+
+ DiscardCurrentFrame();
+
+ if (client_)
+ client_->CurrentSoftwareFrameWasDiscarded();
+}
+
+} // namespace content

Powered by Google App Engine
This is Rietveld 408576698