diff options
author | boliu@chromium.org <boliu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-17 23:35:33 +0000 |
---|---|---|
committer | boliu@chromium.org <boliu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-17 23:35:33 +0000 |
commit | b8ae812b1bf122164de5f0f51c9ce4069b7fdfb9 (patch) | |
tree | 1176001b30f7e5185624b33a5d2036736547f852 /cc | |
parent | 8e6e44ed7090c674297cc0727af1781ebcb50929 (diff) | |
download | chromium_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.cc | 4 | ||||
-rw-r--r-- | cc/resources/raster_worker_pool_unittest.cc | 139 | ||||
-rw-r--r-- | cc/resources/resource_provider.cc | 1 | ||||
-rw-r--r-- | cc/test/test_web_graphics_context_3d.cc | 16 | ||||
-rw-r--r-- | cc/test/test_web_graphics_context_3d.h | 11 |
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_; |