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

Unified Diff: content/browser/compositor/software_output_device_win.cc

Issue 1132133004: Share backing canvases between browser compositors. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 7 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
« no previous file with comments | « content/browser/compositor/software_output_device_win.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/browser/compositor/software_output_device_win.cc
diff --git a/content/browser/compositor/software_output_device_win.cc b/content/browser/compositor/software_output_device_win.cc
index 94ceafd2ebb701aa817650d53e00f63d5d0b7b4c..4ef5957976e4acaecab6dabd719989cde6e04c0c 100644
--- a/content/browser/compositor/software_output_device_win.cc
+++ b/content/browser/compositor/software_output_device_win.cc
@@ -4,6 +4,8 @@
#include "content/browser/compositor/software_output_device_win.h"
+#include "base/memory/shared_memory.h"
+#include "base/memory/singleton.h"
#include "content/public/browser/browser_thread.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkDevice.h"
@@ -15,6 +17,73 @@
namespace content {
+namespace {
+
+class SharedMemoryBacking {
+ public:
+ static SharedMemoryBacking* GetInstance() {
piman 2015/05/11 23:20:56 nit: could the SharedMemoryBacking be owned by the
+ return Singleton<SharedMemoryBacking>::get();
+ }
+
+ void Resized() {
+ size_t new_size = GetMaxByteSize();
+ if (new_size == created_byte_size_)
+ return;
+ for (SoftwareOutputDeviceWin* device : devices_) {
+ device->ReleaseContents();
+ }
+ backing_.reset();
+ created_byte_size_ = 0;
+ }
+
+ void RegisterOutputDevice(SoftwareOutputDeviceWin* device) {
+ devices_.push_back(device);
+ }
+
+ void UnregisterOutputDevice(SoftwareOutputDeviceWin* device) {
+ auto it = std::find(devices_.begin(), devices_.end(), device);
+ DCHECK(it != devices_.end());
+ devices_.erase(it);
+ Resized();
+ }
+
+ base::SharedMemory* GetSharedMemory() {
+ if (backing_)
+ return backing_.get();
+ created_byte_size_ = GetMaxByteSize();
+
+ backing_.reset(new base::SharedMemory);
+ CHECK(backing_->CreateAnonymous(created_byte_size_));
+ return backing_.get();
+ }
+
+ private:
+ SharedMemoryBacking() : created_byte_size_(0) {}
+
+ ~SharedMemoryBacking() {
+ DCHECK(devices_.empty());
+ }
+
+ size_t GetMaxByteSize() {
+ size_t max_size = 0;
+ for (const SoftwareOutputDeviceWin* device : devices_) {
+ max_size = std::max(
+ max_size,
+ static_cast<size_t>(device->viewport_pixel_size().GetArea() * 4));
+ }
+ return max_size;
+ }
+
+ std::vector<SoftwareOutputDeviceWin*> devices_;
+ scoped_ptr<base::SharedMemory> backing_;
+ size_t created_byte_size_;
+ friend struct DefaultSingletonTraits<SharedMemoryBacking>;
+
+ DISALLOW_COPY_AND_ASSIGN(SharedMemoryBacking);
+};
+
+} // namespace
+
SoftwareOutputDeviceWin::SoftwareOutputDeviceWin(ui::Compositor* compositor)
: hwnd_(compositor->widget()),
is_hwnd_composited_(false) {
@@ -23,10 +92,14 @@ SoftwareOutputDeviceWin::SoftwareOutputDeviceWin(ui::Compositor* compositor)
LONG style = GetWindowLong(hwnd_, GWL_EXSTYLE);
is_hwnd_composited_ = !!(style & WS_EX_COMPOSITED);
+ if (!is_hwnd_composited_)
+ SharedMemoryBacking::GetInstance()->RegisterOutputDevice(this);
}
SoftwareOutputDeviceWin::~SoftwareOutputDeviceWin() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (!is_hwnd_composited_)
+ SharedMemoryBacking::GetInstance()->UnregisterOutputDevice(this);
}
void SoftwareOutputDeviceWin::Resize(const gfx::Size& viewport_pixel_size,
@@ -39,19 +112,27 @@ void SoftwareOutputDeviceWin::Resize(const gfx::Size& viewport_pixel_size,
return;
viewport_pixel_size_ = viewport_pixel_size;
- contents_.reset(new gfx::Canvas(viewport_pixel_size, 1.0f, true));
- memset(&bitmap_info_, 0, sizeof(bitmap_info_));
- gfx::CreateBitmapHeader(viewport_pixel_size_.width(),
- viewport_pixel_size_.height(),
- &bitmap_info_.bmiHeader);
+ if (!is_hwnd_composited_)
+ SharedMemoryBacking::GetInstance()->Resized();
+ contents_.reset();
}
SkCanvas* SoftwareOutputDeviceWin::BeginPaint(const gfx::Rect& damage_rect) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DCHECK(contents_);
+ if (!contents_) {
+ HANDLE shared_section = NULL;
+ // Layered windows must be completely updated every time, so they can't
+ // share contents with other windows.
+ if (!is_hwnd_composited_)
piman 2015/05/11 23:20:56 nit: needs {}
+ shared_section =
+ SharedMemoryBacking::GetInstance()->GetSharedMemory()->handle();
+ contents_.reset(skia::CreatePlatformCanvas(
+ viewport_pixel_size_.width(), viewport_pixel_size_.height(), true,
+ shared_section, skia::CRASH_ON_FAILURE));
+ }
damage_rect_ = damage_rect;
- return contents_ ? contents_->sk_canvas() : NULL;
+ return contents_.get();
}
void SoftwareOutputDeviceWin::EndPaint(cc::SoftwareFrameData* frame_data) {
@@ -59,9 +140,6 @@ void SoftwareOutputDeviceWin::EndPaint(cc::SoftwareFrameData* frame_data) {
DCHECK(contents_);
DCHECK(frame_data);
- if (!contents_)
- return;
-
SoftwareOutputDevice::EndPaint(frame_data);
gfx::Rect rect = damage_rect_;
@@ -69,8 +147,6 @@ void SoftwareOutputDeviceWin::EndPaint(cc::SoftwareFrameData* frame_data) {
if (rect.IsEmpty())
return;
- SkCanvas* canvas = contents_->sk_canvas();
- DCHECK(canvas);
if (is_hwnd_composited_) {
RECT wr;
GetWindowRect(hwnd_, &wr);
@@ -84,16 +160,21 @@ void SoftwareOutputDeviceWin::EndPaint(cc::SoftwareFrameData* frame_data) {
style |= WS_EX_LAYERED;
SetWindowLong(hwnd_, GWL_EXSTYLE, style);
- HDC dib_dc = skia::BeginPlatformPaint(canvas);
+ HDC dib_dc = skia::BeginPlatformPaint(contents_.get());
::UpdateLayeredWindow(hwnd_, NULL, &position, &size, dib_dc, &zero,
RGB(0xFF, 0xFF, 0xFF), &blend, ULW_ALPHA);
- skia::EndPlatformPaint(canvas);
+ skia::EndPlatformPaint(contents_.get());
} else {
HDC hdc = ::GetDC(hwnd_);
RECT src_rect = rect.ToRECT();
- skia::DrawToNativeContext(canvas, hdc, rect.x(), rect.y(), &src_rect);
+ skia::DrawToNativeContext(contents_.get(), hdc, rect.x(), rect.y(),
+ &src_rect);
::ReleaseDC(hwnd_, hdc);
}
}
+void SoftwareOutputDeviceWin::ReleaseContents() {
piman 2015/05/11 23:20:56 nit: any way to DCHECK we're not between BeginPain
+ contents_.release();
+}
+
} // namespace content
« no previous file with comments | « content/browser/compositor/software_output_device_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698