summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authorjbauman <jbauman@chromium.org>2015-11-11 15:57:15 -0800
committerCommit bot <commit-bot@chromium.org>2015-11-11 23:58:12 +0000
commit5cfe1a93acf617071b769675b9e890cd4b31a843 (patch)
tree0e436baaeb5e70e2ca8118fdd38443863771ec83 /content
parente7fdcf97fbede6c5d99b2542e7643540f177dc8d (diff)
downloadchromium_src-5cfe1a93acf617071b769675b9e890cd4b31a843.zip
chromium_src-5cfe1a93acf617071b769675b9e890cd4b31a843.tar.gz
chromium_src-5cfe1a93acf617071b769675b9e890cd4b31a843.tar.bz2
Don't attempt to create backing bitmap for extremely large windows.
It's possible in some circumstances that some renderer will attempt to create an extremely large window (e.g. for a very large dropdown). In that case don't crash the browser because of an inability to allocate the backing store for the window, but ignore it and don't attempt to draw to it. BUG=553670 Review URL: https://codereview.chromium.org/1418993009 Cr-Commit-Position: refs/heads/master@{#359188}
Diffstat (limited to 'content')
-rw-r--r--content/browser/compositor/software_output_device_win.cc53
-rw-r--r--content/browser/compositor/software_output_device_win.h2
2 files changed, 43 insertions, 12 deletions
diff --git a/content/browser/compositor/software_output_device_win.cc b/content/browser/compositor/software_output_device_win.cc
index 7f3df87..b4a41ee 100644
--- a/content/browser/compositor/software_output_device_win.cc
+++ b/content/browser/compositor/software_output_device_win.cc
@@ -4,7 +4,9 @@
#include "content/browser/compositor/software_output_device_win.h"
+#include "base/debug/alias.h"
#include "base/memory/shared_memory.h"
+#include "cc/resources/shared_bitmap.h"
#include "content/public/browser/browser_thread.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/skia/include/core/SkBitmap.h"
@@ -15,6 +17,10 @@
namespace content {
+// If a window is larger than this in bytes, don't even try to create a
+// backing bitmap for it.
+static const size_t kMaxBitmapSizeBytes = 4 * (16384 * 8192);
+
OutputDeviceBacking::OutputDeviceBacking() : created_byte_size_(0) {
}
@@ -46,12 +52,21 @@ void OutputDeviceBacking::UnregisterOutputDevice(
Resized();
}
-base::SharedMemory* OutputDeviceBacking::GetSharedMemory() {
+base::SharedMemory* OutputDeviceBacking::GetSharedMemory(
+ const gfx::Size& size) {
if (backing_)
return backing_.get();
- created_byte_size_ = GetMaxByteSize();
+ size_t expected_byte_size = GetMaxByteSize();
+ size_t required_size;
+ if (!cc::SharedBitmap::SizeInBytes(size, &required_size))
+ return nullptr;
+ if (required_size > expected_byte_size)
+ return nullptr;
+
+ created_byte_size_ = expected_byte_size;
backing_.reset(new base::SharedMemory);
+ base::debug::Alias(&expected_byte_size);
CHECK(backing_->CreateAnonymous(created_byte_size_));
return backing_.get();
}
@@ -60,9 +75,13 @@ size_t OutputDeviceBacking::GetMaxByteSize() {
// Minimum byte size is 1 because creating a 0-byte-long SharedMemory fails.
size_t max_size = 1;
for (const SoftwareOutputDeviceWin* device : devices_) {
- max_size = std::max(
- max_size,
- static_cast<size_t>(device->viewport_pixel_size().GetArea() * 4));
+ size_t current_size;
+ if (!cc::SharedBitmap::SizeInBytes(device->viewport_pixel_size(),
+ &current_size))
+ continue;
+ if (current_size > kMaxBitmapSizeBytes)
+ continue;
+ max_size = std::max(max_size, current_size);
}
return max_size;
}
@@ -113,11 +132,21 @@ SkCanvas* SoftwareOutputDeviceWin::BeginPaint(const gfx::Rect& damage_rect) {
DCHECK(!in_paint_);
if (!contents_) {
HANDLE shared_section = NULL;
- if (backing_)
- shared_section = backing_->GetSharedMemory()->handle().GetHandle();
- contents_ = skia::AdoptRef(skia::CreatePlatformCanvas(
- viewport_pixel_size_.width(), viewport_pixel_size_.height(), true,
- shared_section, skia::CRASH_ON_FAILURE));
+ bool can_create_contents = true;
+ if (backing_) {
+ base::SharedMemory* memory =
+ backing_->GetSharedMemory(viewport_pixel_size_);
+ if (memory) {
+ shared_section = memory->handle().GetHandle();
+ } else {
+ can_create_contents = false;
+ }
+ }
+ if (can_create_contents) {
+ contents_ = skia::AdoptRef(skia::CreatePlatformCanvas(
+ viewport_pixel_size_.width(), viewport_pixel_size_.height(), true,
+ shared_section, skia::CRASH_ON_FAILURE));
+ }
}
damage_rect_ = damage_rect;
@@ -127,12 +156,14 @@ SkCanvas* SoftwareOutputDeviceWin::BeginPaint(const gfx::Rect& damage_rect) {
void SoftwareOutputDeviceWin::EndPaint() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DCHECK(contents_);
DCHECK(in_paint_);
in_paint_ = false;
SoftwareOutputDevice::EndPaint();
+ if (!contents_)
+ return;
+
gfx::Rect rect = damage_rect_;
rect.Intersect(gfx::Rect(viewport_pixel_size_));
if (rect.IsEmpty())
diff --git a/content/browser/compositor/software_output_device_win.h b/content/browser/compositor/software_output_device_win.h
index 3f444ae..65de1c4 100644
--- a/content/browser/compositor/software_output_device_win.h
+++ b/content/browser/compositor/software_output_device_win.h
@@ -31,7 +31,7 @@ class OutputDeviceBacking {
void Resized();
void RegisterOutputDevice(SoftwareOutputDeviceWin* device);
void UnregisterOutputDevice(SoftwareOutputDeviceWin* device);
- base::SharedMemory* GetSharedMemory();
+ base::SharedMemory* GetSharedMemory(const gfx::Size& size);
private:
size_t GetMaxByteSize();