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

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 7c6ca0c24fd53a27552363ee3117c8901020d233..bb22e90acd3393d430f5c9a1a82e7e46fc0f1fa0 100644
--- a/content/browser/compositor/software_output_device_win.cc
+++ b/content/browser/compositor/software_output_device_win.cc
@@ -4,33 +4,97 @@
#include "content/browser/compositor/software_output_device_win.h"
+#include "base/memory/shared_memory.h"
#include "content/public/browser/browser_thread.h"
+#include "skia/ext/platform_canvas.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkDevice.h"
#include "ui/compositor/compositor.h"
-#include "ui/gfx/canvas.h"
#include "ui/gfx/gdi_util.h"
#include "ui/gfx/skia_util.h"
namespace content {
-SoftwareOutputDeviceWin::SoftwareOutputDeviceWin(ui::Compositor* compositor)
+OutputDeviceBacking::OutputDeviceBacking() : created_byte_size_(0) {
+}
+
+OutputDeviceBacking::~OutputDeviceBacking() {
+ DCHECK(devices_.empty());
+}
+
+void OutputDeviceBacking::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 OutputDeviceBacking::RegisterOutputDevice(
+ SoftwareOutputDeviceWin* device) {
+ devices_.push_back(device);
+}
+
+void OutputDeviceBacking::UnregisterOutputDevice(
+ SoftwareOutputDeviceWin* device) {
+ auto it = std::find(devices_.begin(), devices_.end(), device);
+ DCHECK(it != devices_.end());
+ devices_.erase(it);
+ Resized();
+}
+
+base::SharedMemory* OutputDeviceBacking::GetSharedMemory() {
+ if (backing_)
+ return backing_.get();
+ created_byte_size_ = GetMaxByteSize();
+
+ backing_.reset(new base::SharedMemory);
+ CHECK(backing_->CreateAnonymous(created_byte_size_));
+ return backing_.get();
+}
+
+size_t OutputDeviceBacking::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;
+}
+
+SoftwareOutputDeviceWin::SoftwareOutputDeviceWin(OutputDeviceBacking* backing,
+ ui::Compositor* compositor)
: hwnd_(compositor->widget()),
- is_hwnd_composited_(false) {
- // TODO(skaslev) Remove this when crbug.com/180702 is fixed.
+ is_hwnd_composited_(false),
+ backing_(backing),
+ in_paint_(false) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
LONG style = GetWindowLong(hwnd_, GWL_EXSTYLE);
is_hwnd_composited_ = !!(style & WS_EX_COMPOSITED);
+ // Layered windows must be completely updated every time, so they can't
+ // share contents with other windows.
+ if (is_hwnd_composited_)
+ backing_ = nullptr;
+ if (backing_)
+ backing_->RegisterOutputDevice(this);
}
SoftwareOutputDeviceWin::~SoftwareOutputDeviceWin() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK(!in_paint_);
+ if (backing_)
+ backing_->UnregisterOutputDevice(this);
}
void SoftwareOutputDeviceWin::Resize(const gfx::Size& viewport_pixel_size,
float scale_factor) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK(!in_paint_);
scale_factor_ = scale_factor;
@@ -38,29 +102,35 @@ 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 (backing_)
+ backing_->Resized();
+ contents_.clear();
}
SkCanvas* SoftwareOutputDeviceWin::BeginPaint(const gfx::Rect& damage_rect) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DCHECK(contents_);
+ DCHECK(!in_paint_);
+ if (!contents_) {
+ HANDLE shared_section = NULL;
+ if (backing_)
+ shared_section = backing_->GetSharedMemory()->handle();
+ contents_ = skia::AdoptRef(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;
+ in_paint_ = true;
+ return contents_.get();
}
void SoftwareOutputDeviceWin::EndPaint(cc::SoftwareFrameData* frame_data) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(contents_);
DCHECK(frame_data);
+ DCHECK(in_paint_);
- if (!contents_)
- return;
-
+ in_paint_ = false;
SoftwareOutputDevice::EndPaint(frame_data);
gfx::Rect rect = damage_rect_;
@@ -68,8 +138,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);
@@ -83,16 +151,23 @@ 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() {
+ DCHECK(!contents_ || contents_->unique());
+ DCHECK(!in_paint_);
+ contents_.clear();
+}
+
} // 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