summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authorboliu@chromium.org <boliu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-17 23:35:33 +0000
committerboliu@chromium.org <boliu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-17 23:35:33 +0000
commitb8ae812b1bf122164de5f0f51c9ce4069b7fdfb9 (patch)
tree1176001b30f7e5185624b33a5d2036736547f852 /cc
parent8e6e44ed7090c674297cc0727af1781ebcb50929 (diff)
downloadchromium_src-b8ae812b1bf122164de5f0f51c9ce4069b7fdfb9.zip
chromium_src-b8ae812b1bf122164de5f0f51c9ce4069b7fdfb9.tar.gz
chromium_src-b8ae812b1bf122164de5f0f51c9ce4069b7fdfb9.tar.bz2
Skip raster if MapImage fails
MapImage should never fail with proper memory management. Android WebView currently lacks memory management and this patch avoids a crash in production (with DCHECK turned off) when MapImage fails. Also add a test for this case for both pixel buffer and image worker pools. BUG=247983 NOTRY=true Review URL: https://chromiumcodereview.appspot.com/16093038 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@206831 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r--cc/resources/image_raster_worker_pool.cc4
-rw-r--r--cc/resources/raster_worker_pool_unittest.cc139
-rw-r--r--cc/resources/resource_provider.cc1
-rw-r--r--cc/test/test_web_graphics_context_3d.cc16
-rw-r--r--cc/test/test_web_graphics_context_3d.h11
5 files changed, 114 insertions, 57 deletions
diff --git a/cc/resources/image_raster_worker_pool.cc b/cc/resources/image_raster_worker_pool.cc
index ac1cdf9..c5ddf2e 100644
--- a/cc/resources/image_raster_worker_pool.cc
+++ b/cc/resources/image_raster_worker_pool.cc
@@ -30,7 +30,9 @@ class ImageWorkerPoolTaskImpl : public internal::WorkerPoolTask {
// Overridden from internal::WorkerPoolTask:
virtual void RunOnThread(unsigned thread_index) OVERRIDE {
- DCHECK(buffer_);
+ if (!buffer_)
+ return;
+
SkBitmap bitmap;
bitmap.setConfig(SkBitmap::kARGB_8888_Config,
task_->resource()->size().width(),
diff --git a/cc/resources/raster_worker_pool_unittest.cc b/cc/resources/raster_worker_pool_unittest.cc
index 4a0af4e..e35518c 100644
--- a/cc/resources/raster_worker_pool_unittest.cc
+++ b/cc/resources/raster_worker_pool_unittest.cc
@@ -19,25 +19,32 @@ namespace cc {
class TestRasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask {
public:
+ typedef base::Callback<void(const PicturePileImpl::Analysis& analysis,
+ bool was_canceled,
+ bool did_raster)> Reply;
+
TestRasterWorkerPoolTaskImpl(
const Resource* resource,
- const RasterWorkerPool::RasterTask::Reply& reply,
+ const Reply& reply,
internal::WorkerPoolTask::TaskVector* dependencies)
: internal::RasterWorkerPoolTask(resource, dependencies),
- reply_(reply) {}
+ reply_(reply),
+ did_raster_(false) {}
virtual bool RunOnThread(SkDevice* device, unsigned thread_index) OVERRIDE {
+ did_raster_ = true;
return true;
}
virtual void DispatchCompletionCallback() OVERRIDE {
- reply_.Run(PicturePileImpl::Analysis(), !HasFinishedRunning());
+ reply_.Run(PicturePileImpl::Analysis(), !HasFinishedRunning(), did_raster_);
}
protected:
virtual ~TestRasterWorkerPoolTaskImpl() {}
private:
- const RasterWorkerPool::RasterTask::Reply reply_;
+ const Reply reply_;
+ bool did_raster_;
};
class RasterWorkerPoolTest : public testing::Test,
@@ -80,16 +87,6 @@ class RasterWorkerPoolTest : public testing::Test,
return raster_worker_pool_.get();
}
- RasterWorkerPool::RasterTask CreateRasterTask(
- const Resource* resource,
- const RasterWorkerPool::RasterTask::Reply& reply,
- RasterWorkerPool::Task::Set& dependencies) {
- return RasterWorkerPool::RasterTask(
- new TestRasterWorkerPoolTaskImpl(resource,
- reply,
- &dependencies.tasks_));
- }
-
void RunTest(bool use_map_image) {
if (use_map_image) {
raster_worker_pool_ = ImageRasterWorkerPool::Create(
@@ -130,6 +127,42 @@ class RasterWorkerPoolTest : public testing::Test,
base::MessageLoop::current()->Quit();
}
+ void ScheduleTasks() {
+ RasterWorkerPool::RasterTask::Queue tasks;
+
+ for (std::vector<RasterWorkerPool::RasterTask>::iterator it =
+ tasks_.begin();
+ it != tasks_.end(); ++it)
+ tasks.Append(*it, false);
+
+ worker_pool()->ScheduleTasks(&tasks);
+ }
+
+ void AppendTask(unsigned id) {
+ const gfx::Size size(1, 1);
+
+ scoped_ptr<ScopedResource> resource(
+ ScopedResource::create(resource_provider()));
+ resource->Allocate(size, GL_RGBA, ResourceProvider::TextureUsageAny);
+ const Resource* const_resource = resource.get();
+
+ RasterWorkerPool::Task::Set empty;
+ tasks_.push_back(
+ RasterWorkerPool::RasterTask(new TestRasterWorkerPoolTaskImpl(
+ const_resource,
+ base::Bind(&RasterWorkerPoolTest::OnTaskCompleted,
+ base::Unretained(this),
+ base::Passed(&resource),
+ id),
+ &empty.tasks_)));
+ }
+
+ virtual void OnTaskCompleted(scoped_ptr<ScopedResource> resource,
+ unsigned id,
+ const PicturePileImpl::Analysis& analysis,
+ bool was_canceled,
+ bool did_raster) {}
+
private:
void ScheduleCheckForCompletedTasks() {
check_.Reset(base::Bind(&RasterWorkerPoolTest::OnCheckForCompletedTasks,
@@ -150,6 +183,7 @@ class RasterWorkerPoolTest : public testing::Test,
base::MessageLoop::current()->Quit();
}
+ protected:
scoped_ptr<FakeOutputSurface> output_surface_;
scoped_ptr<ResourceProvider> resource_provider_;
scoped_ptr<RasterWorkerPool> raster_worker_pool_;
@@ -158,6 +192,7 @@ class RasterWorkerPoolTest : public testing::Test,
base::CancelableClosure timeout_;
int timeout_seconds_;
bool timed_out_;
+ std::vector<RasterWorkerPool::RasterTask> tasks_;
};
namespace {
@@ -178,69 +213,61 @@ namespace {
class BasicRasterWorkerPoolTest : public RasterWorkerPoolTest {
public:
- bool RunRasterTask(SkDevice* device, PicturePileImpl* picture_pile) {
- return true;
- }
-
- void OnTaskCompleted(scoped_ptr<ScopedResource> resource,
- unsigned id,
- const PicturePileImpl::Analysis& analysis,
- bool was_canceled) {
+ virtual void OnTaskCompleted(scoped_ptr<ScopedResource> resource,
+ unsigned id,
+ const PicturePileImpl::Analysis& analysis,
+ bool was_canceled,
+ bool did_raster) OVERRIDE {
+ EXPECT_TRUE(did_raster);
on_task_completed_ids_.push_back(id);
if (on_task_completed_ids_.size() == 2)
EndTest();
}
- void AppendTask(unsigned id) {
- const gfx::Size size(1, 1);
-
- scoped_refptr<PicturePile> picture_pile(new PicturePile);
- picture_pile->set_num_raster_threads(1);
- scoped_refptr<PicturePileImpl> picture_pile_impl(
- PicturePileImpl::CreateFromOther(picture_pile.get(), false));
-
- scoped_ptr<ScopedResource> resource(
- ScopedResource::create(resource_provider()));
- resource->Allocate(size, GL_RGBA, ResourceProvider::TextureUsageAny);
- const Resource* const_resource = resource.get();
-
- RasterWorkerPool::Task::Set empty;
- tasks_.push_back(CreateRasterTask(
- const_resource,
- base::Bind(&BasicRasterWorkerPoolTest::OnTaskCompleted,
- base::Unretained(this),
- base::Passed(&resource),
- id),
- empty));
+ // Overridden from RasterWorkerPoolTest:
+ virtual void BeginTest() OVERRIDE {
+ AppendTask(0u);
+ AppendTask(1u);
+ ScheduleTasks();
+ }
+ virtual void AfterTest() OVERRIDE {
+ EXPECT_EQ(2u, on_task_completed_ids_.size());
+ tasks_.clear();
}
- void ScheduleTasks() {
- RasterWorkerPool::RasterTask::Queue tasks;
+ std::vector<unsigned> on_task_completed_ids_;
+};
- for (std::vector<RasterWorkerPool::RasterTask>::iterator it =
- tasks_.begin();
- it != tasks_.end(); ++it)
- tasks.Append(*it, false);
+PIXEL_BUFFER_AND_IMAGE_TEST_F(BasicRasterWorkerPoolTest);
- worker_pool()->ScheduleTasks(&tasks);
+class RasterWorkerPoolTestFailedMapResource : public RasterWorkerPoolTest {
+ public:
+ virtual void OnTaskCompleted(scoped_ptr<ScopedResource> resource,
+ unsigned id,
+ const PicturePileImpl::Analysis& analysis,
+ bool was_canceled,
+ bool did_raster) OVERRIDE {
+ EXPECT_FALSE(did_raster);
+ EndTest();
}
// Overridden from RasterWorkerPoolTest:
virtual void BeginTest() OVERRIDE {
+ TestWebGraphicsContext3D* context3d =
+ static_cast<TestWebGraphicsContext3D*>(output_surface_->context3d());
+ context3d->set_times_map_image_chromium_succeeds(0);
+ context3d->set_times_map_buffer_chromium_succeeds(0);
AppendTask(0u);
- AppendTask(1u);
ScheduleTasks();
}
+
virtual void AfterTest() OVERRIDE {
- EXPECT_EQ(2u, on_task_completed_ids_.size());
+ ASSERT_EQ(1u, tasks_.size());
tasks_.clear();
}
-
- std::vector<RasterWorkerPool::RasterTask> tasks_;
- std::vector<unsigned> on_task_completed_ids_;
};
-PIXEL_BUFFER_AND_IMAGE_TEST_F(BasicRasterWorkerPoolTest);
+PIXEL_BUFFER_AND_IMAGE_TEST_F(RasterWorkerPoolTestFailedMapResource);
} // namespace
diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc
index da90a44..77f5dde 100644
--- a/cc/resources/resource_provider.cc
+++ b/cc/resources/resource_provider.cc
@@ -1319,6 +1319,7 @@ void ResourceProvider::AcquireImage(ResourceId id) {
DCHECK(context3d);
resource->image_id = context3d->createImageCHROMIUM(
resource->size.width(), resource->size.height(), GL_RGBA8_OES);
+ DCHECK(resource->image_id);
}
void ResourceProvider::ReleaseImage(ResourceId id) {
diff --git a/cc/test/test_web_graphics_context_3d.cc b/cc/test/test_web_graphics_context_3d.cc
index 8956aec..2f1f4c7 100644
--- a/cc/test/test_web_graphics_context_3d.cc
+++ b/cc/test/test_web_graphics_context_3d.cc
@@ -48,6 +48,8 @@ TestWebGraphicsContext3D::TestWebGraphicsContext3D()
times_bind_texture_succeeds_(-1),
times_end_query_succeeds_(-1),
context_lost_(false),
+ times_map_image_chromium_succeeds_(-1),
+ times_map_buffer_chromium_succeeds_(-1),
context_lost_callback_(NULL),
swap_buffers_callback_(NULL),
max_texture_size_(1024),
@@ -72,6 +74,8 @@ TestWebGraphicsContext3D::TestWebGraphicsContext3D(
times_bind_texture_succeeds_(-1),
times_end_query_succeeds_(-1),
context_lost_(false),
+ times_map_image_chromium_succeeds_(-1),
+ times_map_buffer_chromium_succeeds_(-1),
context_lost_callback_(NULL),
swap_buffers_callback_(NULL),
max_texture_size_(1024),
@@ -439,6 +443,12 @@ void* TestWebGraphicsContext3D::mapBufferCHROMIUM(WebKit::WGC3Denum target,
WebKit::WGC3Denum access) {
DCHECK_GT(buffers_.count(bound_buffer_), 0u);
DCHECK_EQ(target, buffers_.get(bound_buffer_)->target);
+ if (times_map_buffer_chromium_succeeds_ >= 0) {
+ if (!times_map_buffer_chromium_succeeds_) {
+ return NULL;
+ }
+ --times_map_buffer_chromium_succeeds_;
+ }
return buffers_.get(bound_buffer_)->pixels.get();
}
@@ -486,6 +496,12 @@ void TestWebGraphicsContext3D::getImageParameterivCHROMIUM(
void* TestWebGraphicsContext3D::mapImageCHROMIUM(WebKit::WGC3Duint image_id,
WebKit::WGC3Denum access) {
DCHECK_GT(images_.count(image_id), 0u);
+ if (times_map_image_chromium_succeeds_ >= 0) {
+ if (!times_map_image_chromium_succeeds_) {
+ return NULL;
+ }
+ --times_map_image_chromium_succeeds_;
+ }
return images_.get(image_id)->pixels.get();
}
diff --git a/cc/test/test_web_graphics_context_3d.h b/cc/test/test_web_graphics_context_3d.h
index bdec155..401fa4a4 100644
--- a/cc/test/test_web_graphics_context_3d.h
+++ b/cc/test/test_web_graphics_context_3d.h
@@ -154,6 +154,15 @@ class TestWebGraphicsContext3D : public FakeWebGraphicsContext3D {
times_end_query_succeeds_ = times;
}
+ // When set, mapImageCHROMIUM and mapBufferCHROMIUM will return NULL after
+ // this many times.
+ void set_times_map_image_chromium_succeeds(int times) {
+ times_map_image_chromium_succeeds_ = times;
+ }
+ void set_times_map_buffer_chromium_succeeds(int times) {
+ times_map_buffer_chromium_succeeds_ = times;
+ }
+
size_t NumTextures() const { return textures_.size(); }
WebKit::WebGLId TextureAt(int i) const { return textures_[i]; }
@@ -207,6 +216,8 @@ class TestWebGraphicsContext3D : public FakeWebGraphicsContext3D {
int times_bind_texture_succeeds_;
int times_end_query_succeeds_;
bool context_lost_;
+ int times_map_image_chromium_succeeds_;
+ int times_map_buffer_chromium_succeeds_;
WebGraphicsContextLostCallback* context_lost_callback_;
WebGraphicsSwapBuffersCompleteCallbackCHROMIUM* swap_buffers_callback_;
std::vector<WebGraphicsSyncPointCallback*> sync_point_callbacks_;