diff options
author | alokp@chromium.org <alokp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-13 03:48:16 +0000 |
---|---|---|
committer | alokp@chromium.org <alokp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-13 03:48:16 +0000 |
commit | cbb74bfde30f13eca4e9b475389db020ff832674 (patch) | |
tree | 6c8552a5457cd92e4aa953b05f9abf8448ce56c1 /cc | |
parent | 0bb15051b0df2705a18c6c931701cb3a686fd0f4 (diff) | |
download | chromium_src-cbb74bfde30f13eca4e9b475389db020ff832674.zip chromium_src-cbb74bfde30f13eca4e9b475389db020ff832674.tar.gz chromium_src-cbb74bfde30f13eca4e9b475389db020ff832674.tar.bz2 |
cc: Refactor WorkerPoolTaskClient::AcquireBufferForRaster
With the introduction of GPU rasterization, we no longer rasterize to a bitmap. We rasterize directly to a texture-backed SkCanvas. This patch refactors AcquireBufferForRaster into AcquireCanvasForRaster to unify the API used by software and gpu rasterization.
It also allows us to cache the gpu canvas with the resource so that we do not need to re-create it whenever a tile needs to be repainted. Creating a new gpu canvas is expensive on command-buffer - both on client and service side. The client side adds a flush every time an FBO is created or destroyed. The service side checks for FBO completeness. This patch eliminates the setup/destroy cost of gpu canvas.
BUG=334492
Review URL: https://codereview.chromium.org/157293002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@250924 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r-- | cc/resources/image_raster_worker_pool.cc | 18 | ||||
-rw-r--r-- | cc/resources/image_raster_worker_pool.h | 4 | ||||
-rw-r--r-- | cc/resources/pixel_buffer_raster_worker_pool.cc | 26 | ||||
-rw-r--r-- | cc/resources/pixel_buffer_raster_worker_pool.h | 4 | ||||
-rw-r--r-- | cc/resources/raster_worker_pool.cc | 115 | ||||
-rw-r--r-- | cc/resources/raster_worker_pool.h | 3 | ||||
-rw-r--r-- | cc/resources/raster_worker_pool_perftest.cc | 3 | ||||
-rw-r--r-- | cc/resources/raster_worker_pool_unittest.cc | 7 | ||||
-rw-r--r-- | cc/resources/resource_provider.cc | 323 | ||||
-rw-r--r-- | cc/resources/resource_provider.h | 163 | ||||
-rw-r--r-- | cc/resources/resource_provider_unittest.cc | 101 | ||||
-rw-r--r-- | cc/test/fake_tile_manager.cc | 4 |
12 files changed, 531 insertions, 240 deletions
diff --git a/cc/resources/image_raster_worker_pool.cc b/cc/resources/image_raster_worker_pool.cc index 16f876c..d4ba08c 100644 --- a/cc/resources/image_raster_worker_pool.cc +++ b/cc/resources/image_raster_worker_pool.cc @@ -140,20 +140,22 @@ void ImageRasterWorkerPool::CheckForCompletedTasks() { CheckForCompletedGpuRasterTasks(); } -void* ImageRasterWorkerPool::AcquireBufferForRaster( - internal::RasterWorkerPoolTask* task, - int* stride) { - // Acquire image for resource. - resource_provider()->AcquireImage(task->resource()->id()); +SkCanvas* ImageRasterWorkerPool::AcquireCanvasForRaster( + internal::RasterWorkerPoolTask* task) { + if (task->use_gpu_rasterization()) + return resource_provider()->MapDirectRasterBuffer(task->resource()->id()); - *stride = resource_provider()->GetImageStride(task->resource()->id()); - return resource_provider()->MapImage(task->resource()->id()); + return resource_provider()->MapImageRasterBuffer(task->resource()->id()); } void ImageRasterWorkerPool::OnRasterCompleted( internal::RasterWorkerPoolTask* task, const PicturePileImpl::Analysis& analysis) { - resource_provider()->UnmapImage(task->resource()->id()); + if (task->use_gpu_rasterization()) { + resource_provider()->UnmapDirectRasterBuffer(task->resource()->id()); + return; + } + resource_provider()->UnmapImageRasterBuffer(task->resource()->id()); } void ImageRasterWorkerPool::OnImageDecodeCompleted( diff --git a/cc/resources/image_raster_worker_pool.h b/cc/resources/image_raster_worker_pool.h index a944f7f..b3b8ad8 100644 --- a/cc/resources/image_raster_worker_pool.h +++ b/cc/resources/image_raster_worker_pool.h @@ -25,8 +25,8 @@ class CC_EXPORT ImageRasterWorkerPool : public RasterWorkerPool { virtual void CheckForCompletedTasks() OVERRIDE; // Overridden from internal::WorkerPoolTaskClient: - virtual void* AcquireBufferForRaster(internal::RasterWorkerPoolTask* task, - int* stride) OVERRIDE; + virtual SkCanvas* AcquireCanvasForRaster(internal::RasterWorkerPoolTask* task) + OVERRIDE; virtual void OnRasterCompleted(internal::RasterWorkerPoolTask* task, const PicturePileImpl::Analysis& analysis) OVERRIDE; diff --git a/cc/resources/pixel_buffer_raster_worker_pool.cc b/cc/resources/pixel_buffer_raster_worker_pool.cc index 0bf2d3f..ac5ea85 100644 --- a/cc/resources/pixel_buffer_raster_worker_pool.cc +++ b/cc/resources/pixel_buffer_raster_worker_pool.cc @@ -227,19 +227,23 @@ void PixelBufferRasterWorkerPool::CheckForCompletedTasks() { CheckForCompletedGpuRasterTasks(); } -void* PixelBufferRasterWorkerPool::AcquireBufferForRaster( - internal::RasterWorkerPoolTask* task, - int* stride) { - // Request a pixel buffer. This will reserve shared memory. - resource_provider()->AcquirePixelBuffer(task->resource()->id()); +SkCanvas* PixelBufferRasterWorkerPool::AcquireCanvasForRaster( + internal::RasterWorkerPoolTask* task) { + if (task->use_gpu_rasterization()) + return resource_provider()->MapDirectRasterBuffer(task->resource()->id()); - *stride = 0; - return resource_provider()->MapPixelBuffer(task->resource()->id()); + resource_provider()->AcquirePixelRasterBuffer(task->resource()->id()); + return resource_provider()->MapPixelRasterBuffer(task->resource()->id()); } void PixelBufferRasterWorkerPool::OnRasterCompleted( internal::RasterWorkerPoolTask* task, const PicturePileImpl::Analysis& analysis) { + if (task->use_gpu_rasterization()) { + resource_provider()->UnmapDirectRasterBuffer(task->resource()->id()); + return; + } + TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("cc"), "PixelBufferRasterWorkerPool::OnRasterCompleted", "was_canceled", @@ -250,11 +254,11 @@ void PixelBufferRasterWorkerPool::OnRasterCompleted( DCHECK(raster_task_states_.find(task) != raster_task_states_.end()); DCHECK_EQ(SCHEDULED, raster_task_states_[task]); - // Balanced with MapPixelBuffer() call in AcquireBufferForRaster(). - resource_provider()->UnmapPixelBuffer(task->resource()->id()); + // Balanced with MapPixelRasterBuffer() call in AcquireCanvasForRaster(). + resource_provider()->UnmapPixelRasterBuffer(task->resource()->id()); if (!task->HasFinishedRunning() || analysis.is_solid_color) { - resource_provider()->ReleasePixelBuffer(task->resource()->id()); + resource_provider()->ReleasePixelRasterBuffer(task->resource()->id()); if (!task->HasFinishedRunning()) { // When priorites change, a raster task can be canceled as a result of @@ -387,7 +391,7 @@ void PixelBufferRasterWorkerPool::CheckForCompletedUploads() { tasks_with_completed_uploads.front().get(); // It's now safe to release the pixel buffer and the shared memory. - resource_provider()->ReleasePixelBuffer(task->resource()->id()); + resource_provider()->ReleasePixelRasterBuffer(task->resource()->id()); bytes_pending_upload_ -= task->resource()->bytes(); diff --git a/cc/resources/pixel_buffer_raster_worker_pool.h b/cc/resources/pixel_buffer_raster_worker_pool.h index 2530e89..a658484 100644 --- a/cc/resources/pixel_buffer_raster_worker_pool.h +++ b/cc/resources/pixel_buffer_raster_worker_pool.h @@ -40,8 +40,8 @@ class CC_EXPORT PixelBufferRasterWorkerPool : public RasterWorkerPool { virtual void CheckForCompletedTasks() OVERRIDE; // Overridden from internal::WorkerPoolTaskClient: - virtual void* AcquireBufferForRaster(internal::RasterWorkerPoolTask* task, - int* stride) OVERRIDE; + virtual SkCanvas* AcquireCanvasForRaster(internal::RasterWorkerPoolTask* task) + OVERRIDE; virtual void OnRasterCompleted(internal::RasterWorkerPoolTask* task, const PicturePileImpl::Analysis& analysis) OVERRIDE; diff --git a/cc/resources/raster_worker_pool.cc b/cc/resources/raster_worker_pool.cc index d6cbe67..630640b 100644 --- a/cc/resources/raster_worker_pool.cc +++ b/cc/resources/raster_worker_pool.cc @@ -22,7 +22,6 @@ #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkPixelRef.h" #include "third_party/skia/include/gpu/GrContext.h" -#include "third_party/skia/include/gpu/SkGpuDevice.h" namespace cc { namespace { @@ -96,8 +95,7 @@ class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { source_frame_number_(source_frame_number), rendering_stats_(rendering_stats), reply_(reply), - buffer_(NULL), - stride_(0) {} + canvas_(NULL) {} void RunAnalysisOnThread(unsigned thread_index) { TRACE_EVENT1("cc", @@ -124,10 +122,7 @@ class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { analysis_.is_solid_color &= kUseColorEstimator; } - void RunRasterOnThread(unsigned thread_index, - void* buffer, - const gfx::Size& size, - int stride) { + void RunRasterOnThread(unsigned thread_index) { TRACE_EVENT2( "cc", "RasterWorkerPoolTaskImpl::RunRasterOnThread", @@ -140,34 +135,7 @@ class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { devtools_instrumentation::kRasterTask, layer_id_); DCHECK(picture_pile_.get()); - DCHECK(buffer); - - SkBitmap bitmap; - switch (resource()->format()) { - case RGBA_4444: - // Use the default stride if we will eventually convert this - // bitmap to 4444. - bitmap.setConfig( - SkBitmap::kARGB_8888_Config, size.width(), size.height()); - bitmap.allocPixels(); - break; - case RGBA_8888: - case BGRA_8888: - bitmap.setConfig( - SkBitmap::kARGB_8888_Config, size.width(), size.height(), stride); - bitmap.setPixels(buffer); - break; - case LUMINANCE_8: - case RGB_565: - case ETC1: - NOTREACHED(); - break; - } - - SkBitmapDevice device(bitmap); - SkCanvas canvas(&device); - Raster(picture_pile_->GetCloneForDrawingOnThread(thread_index), &canvas); - ChangeBitmapConfigIfNeeded(bitmap, buffer); + Raster(picture_pile_->GetCloneForDrawingOnThread(thread_index)); } // Overridden from internal::Task: @@ -175,27 +143,23 @@ class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { // TODO(alokp): For now run-on-worker-thread implies software rasterization. DCHECK(!use_gpu_rasterization()); RunAnalysisOnThread(thread_index); - if (buffer_ && !analysis_.is_solid_color) - RunRasterOnThread(thread_index, buffer_, resource()->size(), stride_); + if (canvas_ && !analysis_.is_solid_color) + RunRasterOnThread(thread_index); } // Overridden from internal::WorkerPoolTask: virtual void ScheduleOnOriginThread(internal::WorkerPoolTaskClient* client) OVERRIDE { - if (use_gpu_rasterization()) - return; - DCHECK(!buffer_); - buffer_ = client->AcquireBufferForRaster(this, &stride_); + DCHECK(!canvas_); + canvas_ = client->AcquireCanvasForRaster(this); } virtual void CompleteOnOriginThread(internal::WorkerPoolTaskClient* client) OVERRIDE { - if (use_gpu_rasterization()) - return; - buffer_ = NULL; + canvas_ = NULL; client->OnRasterCompleted(this, analysis_); } virtual void RunReplyOnOriginThread() OVERRIDE { - DCHECK(!buffer_); + DCHECK(!canvas_); reply_.Run(analysis_, !HasFinishedRunning()); } @@ -212,31 +176,12 @@ class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { .c_str()); // TODO(alokp): For now run-on-origin-thread implies gpu rasterization. DCHECK(use_gpu_rasterization()); - ResourceProvider::ScopedWriteLockGL lock(resource_provider, - resource()->id()); - DCHECK_NE(lock.texture_id(), 0u); - - GrBackendTextureDesc desc; - desc.fFlags = kRenderTarget_GrBackendTextureFlag; - desc.fWidth = content_rect_.width(); - desc.fHeight = content_rect_.height(); - desc.fConfig = ToGrFormat(resource()->format()); - desc.fOrigin = kTopLeft_GrSurfaceOrigin; - desc.fTextureHandle = lock.texture_id(); - - GrContext* gr_context = context_provider->GrContext(); - skia::RefPtr<GrTexture> texture = - skia::AdoptRef(gr_context->wrapBackendTexture(desc)); - skia::RefPtr<SkGpuDevice> device = - skia::AdoptRef(SkGpuDevice::Create(texture.get())); - skia::RefPtr<SkCanvas> canvas = skia::AdoptRef(new SkCanvas(device.get())); - - Raster(picture_pile_, canvas.get()); + Raster(picture_pile_); context_provider->ContextGL()->PopGroupMarkerEXT(); } protected: - virtual ~RasterWorkerPoolTaskImpl() { DCHECK(!buffer_); } + virtual ~RasterWorkerPoolTaskImpl() { DCHECK(!canvas_); } private: scoped_ptr<base::Value> DataAsValue() const { @@ -248,22 +193,7 @@ class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { return res.PassAs<base::Value>(); } - static GrPixelConfig ToGrFormat(ResourceFormat format) { - switch (format) { - case RGBA_8888: - return kRGBA_8888_GrPixelConfig; - case BGRA_8888: - return kBGRA_8888_GrPixelConfig; - case RGBA_4444: - return kRGBA_4444_GrPixelConfig; - default: - break; - } - DCHECK(false) << "Unsupported resource format."; - return kSkia8888_GrPixelConfig; - } - - void Raster(PicturePileImpl* picture_pile, SkCanvas* canvas) { + void Raster(PicturePileImpl* picture_pile) { skia::RefPtr<SkDrawFilter> draw_filter; switch (raster_mode_) { case LOW_QUALITY_RASTER_MODE: @@ -278,7 +208,7 @@ class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { default: NOTREACHED(); } - canvas->setDrawFilter(draw_filter.get()); + canvas_->setDrawFilter(draw_filter.get()); base::TimeDelta prev_rasterize_time = rendering_stats_->impl_thread_rendering_stats().rasterize_time; @@ -289,7 +219,8 @@ class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { // before we draw and sometimes they aren't) RenderingStatsInstrumentation* stats = tile_resolution_ == HIGH_RESOLUTION ? rendering_stats_ : NULL; - picture_pile->RasterToBitmap(canvas, content_rect_, contents_scale_, stats); + picture_pile->RasterToBitmap( + canvas_, content_rect_, contents_scale_, stats); if (rendering_stats_->record_rendering_stats()) { base::TimeDelta current_rasterize_time = @@ -303,19 +234,6 @@ class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { } } - void ChangeBitmapConfigIfNeeded(const SkBitmap& bitmap, void* buffer) { - TRACE_EVENT0("cc", "RasterWorkerPoolTaskImpl::ChangeBitmapConfigIfNeeded"); - SkBitmap::Config config = SkBitmapConfig(resource()->format()); - if (bitmap.getConfig() != config) { - SkBitmap bitmap_dest; - IdentityAllocator allocator(buffer); - bitmap.copyTo(&bitmap_dest, config, &allocator); - // TODO(kaanb): The GL pipeline assumes a 4-byte alignment for the - // bitmap data. This check will be removed once crbug.com/293728 is fixed. - CHECK_EQ(0u, bitmap_dest.rowBytes() % 4); - } - } - PicturePileImpl::Analysis analysis_; scoped_refptr<PicturePileImpl> picture_pile_; gfx::Rect content_rect_; @@ -327,8 +245,7 @@ class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { int source_frame_number_; RenderingStatsInstrumentation* rendering_stats_; const RasterWorkerPool::RasterTask::Reply reply_; - void* buffer_; - int stride_; + SkCanvas* canvas_; DISALLOW_COPY_AND_ASSIGN(RasterWorkerPoolTaskImpl); }; diff --git a/cc/resources/raster_worker_pool.h b/cc/resources/raster_worker_pool.h index a8fb2fc..389ac41 100644 --- a/cc/resources/raster_worker_pool.h +++ b/cc/resources/raster_worker_pool.h @@ -30,8 +30,7 @@ class RasterWorkerPoolTask; class CC_EXPORT WorkerPoolTaskClient { public: - virtual void* AcquireBufferForRaster(RasterWorkerPoolTask* task, - int* stride) = 0; + virtual SkCanvas* AcquireCanvasForRaster(RasterWorkerPoolTask* task) = 0; virtual void OnRasterCompleted(RasterWorkerPoolTask* task, const PicturePileImpl::Analysis& analysis) = 0; virtual void OnImageDecodeCompleted(WorkerPoolTask* task) = 0; diff --git a/cc/resources/raster_worker_pool_perftest.cc b/cc/resources/raster_worker_pool_perftest.cc index 5ceeebe..703a95d 100644 --- a/cc/resources/raster_worker_pool_perftest.cc +++ b/cc/resources/raster_worker_pool_perftest.cc @@ -68,8 +68,7 @@ class PerfRasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { // Overridden from internal::WorkerPoolTask: virtual void ScheduleOnOriginThread(internal::WorkerPoolTaskClient* client) OVERRIDE { - int stride; - client->AcquireBufferForRaster(this, &stride); + client->AcquireCanvasForRaster(this); } virtual void CompleteOnOriginThread(internal::WorkerPoolTaskClient* client) OVERRIDE { diff --git a/cc/resources/raster_worker_pool_unittest.cc b/cc/resources/raster_worker_pool_unittest.cc index 0d236f1..73debb4 100644 --- a/cc/resources/raster_worker_pool_unittest.cc +++ b/cc/resources/raster_worker_pool_unittest.cc @@ -57,15 +57,10 @@ class TestRasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { // Overridden from internal::WorkerPoolTask: virtual void ScheduleOnOriginThread(internal::WorkerPoolTaskClient* client) OVERRIDE { - if (use_gpu_rasterization()) - return; - int stride; - client->AcquireBufferForRaster(this, &stride); + client->AcquireCanvasForRaster(this); } virtual void CompleteOnOriginThread(internal::WorkerPoolTaskClient* client) OVERRIDE { - if (use_gpu_rasterization()) - return; client->OnRasterCompleted(this, PicturePileImpl::Analysis()); } virtual void RunReplyOnOriginThread() OVERRIDE { diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc index bbb3772..bd2b5a8 100644 --- a/cc/resources/resource_provider.cc +++ b/cc/resources/resource_provider.cc @@ -23,6 +23,9 @@ #include "gpu/command_buffer/client/gles2_interface.h" #include "third_party/khronos/GLES2/gl2.h" #include "third_party/khronos/GLES2/gl2ext.h" +#include "third_party/skia/include/core/SkSurface.h" +#include "third_party/skia/include/gpu/GrContext.h" +#include "third_party/skia/include/gpu/SkGpuDevice.h" #include "ui/gfx/frame_time.h" #include "ui/gfx/rect.h" #include "ui/gfx/vector2d.h" @@ -91,6 +94,44 @@ bool IsFormatSupportedForStorage(ResourceFormat format) { return false; } +GrPixelConfig ToGrPixelConfig(ResourceFormat format) { + switch (format) { + case RGBA_8888: + return kRGBA_8888_GrPixelConfig; + case BGRA_8888: + return kBGRA_8888_GrPixelConfig; + case RGBA_4444: + return kRGBA_4444_GrPixelConfig; + default: + break; + } + DCHECK(false) << "Unsupported resource format."; + return kSkia8888_GrPixelConfig; +} + +class IdentityAllocator : public SkBitmap::Allocator { + public: + explicit IdentityAllocator(void* buffer) : buffer_(buffer) {} + virtual bool allocPixelRef(SkBitmap* dst, SkColorTable*) OVERRIDE { + dst->setPixels(buffer_); + return true; + } + + private: + void* buffer_; +}; + +void CopyBitmap(const SkBitmap& src, + uint8_t* dst, + SkBitmap::Config dst_config) { + SkBitmap dst_bitmap; + IdentityAllocator allocator(dst); + src.copyTo(&dst_bitmap, dst_config, &allocator); + // TODO(kaanb): The GL pipeline assumes a 4-byte alignment for the + // bitmap data. This check will be removed once crbug.com/293728 is fixed. + CHECK_EQ(0u, dst_bitmap.rowBytes() % 4); +} + class ScopedSetActiveTexture { public: ScopedSetActiveTexture(GLES2Interface* gl, GLenum unit) @@ -327,6 +368,175 @@ ResourceProvider::Resource::Resource(const SharedBitmapId& bitmap_id, DCHECK(wrap_mode == GL_CLAMP_TO_EDGE || wrap_mode == GL_REPEAT); } +ResourceProvider::RasterBuffer::RasterBuffer( + const Resource* resource, + ResourceProvider* resource_provider) + : resource_(resource), + resource_provider_(resource_provider), + locked_canvas_(NULL), + canvas_save_count_(0) { + DCHECK(resource_); + DCHECK(resource_provider_); +} + +ResourceProvider::RasterBuffer::~RasterBuffer() {} + +SkCanvas* ResourceProvider::RasterBuffer::LockForWrite() { + DCHECK(!locked_canvas_); + + locked_canvas_ = DoLockForWrite(); + canvas_save_count_ = locked_canvas_ ? locked_canvas_->save() : 0; + return locked_canvas_; +} + +void ResourceProvider::RasterBuffer::UnlockForWrite() { + if (locked_canvas_) { + locked_canvas_->restoreToCount(canvas_save_count_); + locked_canvas_ = NULL; + } + DoUnlockForWrite(); +} + +ResourceProvider::DirectRasterBuffer::DirectRasterBuffer( + const Resource* resource, + ResourceProvider* resource_provider) + : RasterBuffer(resource, resource_provider) {} + +ResourceProvider::DirectRasterBuffer::~DirectRasterBuffer() {} + +SkCanvas* ResourceProvider::DirectRasterBuffer::DoLockForWrite() { + if (!surface_) + surface_ = CreateSurface(); + return surface_ ? surface_->getCanvas() : NULL; +} + +void ResourceProvider::DirectRasterBuffer::DoUnlockForWrite() {} + +skia::RefPtr<SkSurface> ResourceProvider::DirectRasterBuffer::CreateSurface() { + skia::RefPtr<SkSurface> surface; + switch (resource()->type) { + case GLTexture: { + DCHECK(resource()->gl_id); + class GrContext* gr_context = resource_provider()->GrContext(); + if (gr_context) { + GrBackendTextureDesc desc; + desc.fFlags = kRenderTarget_GrBackendTextureFlag; + desc.fWidth = resource()->size.width(); + desc.fHeight = resource()->size.height(); + desc.fConfig = ToGrPixelConfig(resource()->format); + desc.fOrigin = kTopLeft_GrSurfaceOrigin; + desc.fTextureHandle = resource()->gl_id; + skia::RefPtr<GrTexture> gr_texture = + skia::AdoptRef(gr_context->wrapBackendTexture(desc)); + surface = skia::AdoptRef( + SkSurface::NewRenderTargetDirect(gr_texture->asRenderTarget())); + } + break; + } + case Bitmap: { + DCHECK(resource()->pixels); + DCHECK_EQ(RGBA_8888, resource()->format); + SkImageInfo image_info = SkImageInfo::MakeN32Premul( + resource()->size.width(), resource()->size.height()); + size_t row_bytes = SkBitmap::ComputeRowBytes(SkBitmap::kARGB_8888_Config, + resource()->size.width()); + surface = skia::AdoptRef(SkSurface::NewRasterDirect( + image_info, resource()->pixels, row_bytes)); + break; + } + default: + NOTREACHED(); + } + return surface; +} + +ResourceProvider::BitmapRasterBuffer::BitmapRasterBuffer( + const Resource* resource, + ResourceProvider* resource_provider) + : RasterBuffer(resource, resource_provider), mapped_buffer_(NULL) {} + +ResourceProvider::BitmapRasterBuffer::~BitmapRasterBuffer() {} + +SkCanvas* ResourceProvider::BitmapRasterBuffer::DoLockForWrite() { + DCHECK(!mapped_buffer_); + DCHECK(!raster_canvas_); + + int stride = 0; + mapped_buffer_ = MapBuffer(&stride); + if (!mapped_buffer_) + return NULL; + + switch (resource()->format) { + case RGBA_4444: + // Use the default stride if we will eventually convert this + // bitmap to 4444. + raster_bitmap_.setConfig(SkBitmap::kARGB_8888_Config, + resource()->size.width(), + resource()->size.height()); + raster_bitmap_.allocPixels(); + break; + case RGBA_8888: + case BGRA_8888: + raster_bitmap_.setConfig(SkBitmap::kARGB_8888_Config, + resource()->size.width(), + resource()->size.height(), + stride); + raster_bitmap_.setPixels(mapped_buffer_); + break; + case LUMINANCE_8: + case RGB_565: + case ETC1: + NOTREACHED(); + break; + } + skia::RefPtr<SkBitmapDevice> device = + skia::AdoptRef(new SkBitmapDevice(raster_bitmap_)); + raster_canvas_ = skia::AdoptRef(new SkCanvas(device.get())); + return raster_canvas_.get(); +} + +void ResourceProvider::BitmapRasterBuffer::DoUnlockForWrite() { + raster_canvas_.clear(); + + SkBitmap::Config buffer_config = SkBitmapConfig(resource()->format); + if (mapped_buffer_ && (buffer_config != raster_bitmap_.config())) + CopyBitmap(raster_bitmap_, mapped_buffer_, buffer_config); + raster_bitmap_.reset(); + + UnmapBuffer(); + mapped_buffer_ = NULL; +} + +ResourceProvider::ImageRasterBuffer::ImageRasterBuffer( + const Resource* resource, + ResourceProvider* resource_provider) + : BitmapRasterBuffer(resource, resource_provider) {} + +ResourceProvider::ImageRasterBuffer::~ImageRasterBuffer() {} + +uint8_t* ResourceProvider::ImageRasterBuffer::MapBuffer(int* stride) { + return resource_provider()->MapImage(resource(), stride); +} + +void ResourceProvider::ImageRasterBuffer::UnmapBuffer() { + resource_provider()->UnmapImage(resource()); +} + +ResourceProvider::PixelRasterBuffer::PixelRasterBuffer( + const Resource* resource, + ResourceProvider* resource_provider) + : BitmapRasterBuffer(resource, resource_provider) {} + +ResourceProvider::PixelRasterBuffer::~PixelRasterBuffer() {} + +uint8_t* ResourceProvider::PixelRasterBuffer::MapBuffer(int* stride) { + return resource_provider()->MapPixelBuffer(resource(), stride); +} + +void ResourceProvider::PixelRasterBuffer::UnmapBuffer() { + resource_provider()->UnmapPixelBuffer(resource()); +} + ResourceProvider::Child::Child() : marked_for_deletion(false) {} ResourceProvider::Child::~Child() {} @@ -584,6 +794,10 @@ void ResourceProvider::DeleteResourceInternal(ResourceMap::iterator it, if (style == ForShutdown && resource->exported_count > 0) lost_resource = true; + resource->direct_raster_buffer.reset(); + resource->image_raster_buffer.reset(); + resource->pixel_raster_buffer.reset(); + if (resource->image_id) { DCHECK(resource->origin == Resource::Internal); GLES2Interface* gl = ContextGL(); @@ -1472,8 +1686,64 @@ void ResourceProvider::DeleteAndReturnUnusedResourcesToChild( } } -void ResourceProvider::AcquirePixelBuffer(ResourceId id) { +SkCanvas* ResourceProvider::MapDirectRasterBuffer(ResourceId id) { + // Resource needs to be locked for write since DirectRasterBuffer writes + // directly to it. + LockForWrite(id); + Resource* resource = GetResource(id); + if (!resource->direct_raster_buffer.get()) { + resource->direct_raster_buffer.reset( + new DirectRasterBuffer(resource, this)); + } + return resource->direct_raster_buffer->LockForWrite(); +} + +void ResourceProvider::UnmapDirectRasterBuffer(ResourceId id) { + Resource* resource = GetResource(id); + DCHECK(resource->direct_raster_buffer.get()); + resource->direct_raster_buffer->UnlockForWrite(); + UnlockForWrite(id); +} + +SkCanvas* ResourceProvider::MapImageRasterBuffer(ResourceId id) { + Resource* resource = GetResource(id); + AcquireImage(resource); + if (!resource->image_raster_buffer.get()) + resource->image_raster_buffer.reset(new ImageRasterBuffer(resource, this)); + return resource->image_raster_buffer->LockForWrite(); +} + +void ResourceProvider::UnmapImageRasterBuffer(ResourceId id) { + Resource* resource = GetResource(id); + resource->image_raster_buffer->UnlockForWrite(); + resource->dirty_image = true; +} + +void ResourceProvider::AcquirePixelRasterBuffer(ResourceId id) { Resource* resource = GetResource(id); + AcquirePixelBuffer(resource); + resource->pixel_raster_buffer.reset(new PixelRasterBuffer(resource, this)); +} + +void ResourceProvider::ReleasePixelRasterBuffer(ResourceId id) { + Resource* resource = GetResource(id); + resource->pixel_raster_buffer.reset(); + ReleasePixelBuffer(resource); +} + +SkCanvas* ResourceProvider::MapPixelRasterBuffer(ResourceId id) { + Resource* resource = GetResource(id); + DCHECK(resource->pixel_raster_buffer.get()); + return resource->pixel_raster_buffer->LockForWrite(); +} + +void ResourceProvider::UnmapPixelRasterBuffer(ResourceId id) { + Resource* resource = GetResource(id); + DCHECK(resource->pixel_raster_buffer.get()); + resource->pixel_raster_buffer->UnlockForWrite(); +} + +void ResourceProvider::AcquirePixelBuffer(Resource* resource) { DCHECK(resource->origin == Resource::Internal); DCHECK_EQ(resource->exported_count, 0); DCHECK(!resource->image_id); @@ -1502,8 +1772,7 @@ void ResourceProvider::AcquirePixelBuffer(ResourceId id) { } } -void ResourceProvider::ReleasePixelBuffer(ResourceId id) { - Resource* resource = GetResource(id); +void ResourceProvider::ReleasePixelBuffer(Resource* resource) { DCHECK(resource->origin == Resource::Internal); DCHECK_EQ(resource->exported_count, 0); DCHECK(!resource->image_id); @@ -1517,7 +1786,7 @@ void ResourceProvider::ReleasePixelBuffer(ResourceId id) { if (resource->pending_set_pixels) { DCHECK(resource->set_pixels_completion_forced); resource->pending_set_pixels = false; - UnlockForWrite(id); + resource->locked_for_write = false; } if (resource->type == GLTexture) { @@ -1539,12 +1808,13 @@ void ResourceProvider::ReleasePixelBuffer(ResourceId id) { } } -uint8_t* ResourceProvider::MapPixelBuffer(ResourceId id) { - Resource* resource = GetResource(id); +uint8_t* ResourceProvider::MapPixelBuffer(const Resource* resource, + int* stride) { DCHECK(resource->origin == Resource::Internal); DCHECK_EQ(resource->exported_count, 0); DCHECK(!resource->image_id); + *stride = 0; if (resource->type == GLTexture) { GLES2Interface* gl = ContextGL(); DCHECK(gl); @@ -1562,8 +1832,7 @@ uint8_t* ResourceProvider::MapPixelBuffer(ResourceId id) { return resource->pixel_buffer; } -void ResourceProvider::UnmapPixelBuffer(ResourceId id) { - Resource* resource = GetResource(id); +void ResourceProvider::UnmapPixelBuffer(const Resource* resource) { DCHECK(resource->origin == Resource::Internal); DCHECK_EQ(resource->exported_count, 0); DCHECK(!resource->image_id); @@ -1815,8 +2084,7 @@ void ResourceProvider::EnableReadLockFences(ResourceProvider::ResourceId id, resource->enable_read_lock_fences = enable; } -void ResourceProvider::AcquireImage(ResourceId id) { - Resource* resource = GetResource(id); +void ResourceProvider::AcquireImage(Resource* resource) { DCHECK(resource->origin == Resource::Internal); DCHECK_EQ(resource->exported_count, 0); @@ -1836,8 +2104,7 @@ void ResourceProvider::AcquireImage(ResourceId id) { DCHECK(resource->image_id); } -void ResourceProvider::ReleaseImage(ResourceId id) { - Resource* resource = GetResource(id); +void ResourceProvider::ReleaseImage(Resource* resource) { DCHECK(resource->origin == Resource::Internal); DCHECK_EQ(resource->exported_count, 0); @@ -1853,8 +2120,7 @@ void ResourceProvider::ReleaseImage(ResourceId id) { resource->allocated = false; } -uint8_t* ResourceProvider::MapImage(ResourceId id) { - Resource* resource = GetResource(id); +uint8_t* ResourceProvider::MapImage(const Resource* resource, int* stride) { DCHECK(ReadLockFenceHasPassed(resource)); DCHECK(resource->origin == Resource::Internal); DCHECK_EQ(resource->exported_count, 0); @@ -1863,15 +2129,17 @@ uint8_t* ResourceProvider::MapImage(ResourceId id) { DCHECK(resource->image_id); GLES2Interface* gl = ContextGL(); DCHECK(gl); + gl->GetImageParameterivCHROMIUM( + resource->image_id, GL_IMAGE_ROWBYTES_CHROMIUM, stride); return static_cast<uint8_t*>( gl->MapImageCHROMIUM(resource->image_id, GL_READ_WRITE)); } DCHECK_EQ(Bitmap, resource->type); + *stride = 0; return resource->pixels; } -void ResourceProvider::UnmapImage(ResourceId id) { - Resource* resource = GetResource(id); +void ResourceProvider::UnmapImage(const Resource* resource) { DCHECK(resource->origin == Resource::Internal); DCHECK_EQ(resource->exported_count, 0); @@ -1879,27 +2147,9 @@ void ResourceProvider::UnmapImage(ResourceId id) { GLES2Interface* gl = ContextGL(); DCHECK(gl); gl->UnmapImageCHROMIUM(resource->image_id); - resource->dirty_image = true; } } -int ResourceProvider::GetImageStride(ResourceId id) { - Resource* resource = GetResource(id); - DCHECK(resource->origin == Resource::Internal); - DCHECK_EQ(resource->exported_count, 0); - - int stride = 0; - - if (resource->image_id) { - GLES2Interface* gl = ContextGL(); - DCHECK(gl); - gl->GetImageParameterivCHROMIUM( - resource->image_id, GL_IMAGE_ROWBYTES_CHROMIUM, &stride); - } - - return stride; -} - GLint ResourceProvider::GetActiveTextureUnit(GLES2Interface* gl) { GLint active_unit = 0; gl->GetIntegerv(GL_ACTIVE_TEXTURE, &active_unit); @@ -1911,4 +2161,9 @@ GLES2Interface* ResourceProvider::ContextGL() const { return context_provider ? context_provider->ContextGL() : NULL; } +class GrContext* ResourceProvider::GrContext() const { + ContextProvider* context_provider = output_surface_->context_provider(); + return context_provider ? context_provider->GrContext() : NULL; +} + } // namespace cc diff --git a/cc/resources/resource_provider.h b/cc/resources/resource_provider.h index 4988bc0..dd7e200 100644 --- a/cc/resources/resource_provider.h +++ b/cc/resources/resource_provider.h @@ -14,6 +14,7 @@ #include "base/basictypes.h" #include "base/callback.h" #include "base/containers/hash_tables.h" +#include "base/memory/linked_ptr.h" #include "base/memory/scoped_ptr.h" #include "base/threading/thread_checker.h" #include "cc/base/cc_export.h" @@ -32,6 +33,8 @@ #include "third_party/skia/include/core/SkCanvas.h" #include "ui/gfx/size.h" +class GrContext; + namespace gpu { namespace gles { class GLES2Interface; @@ -314,33 +317,34 @@ class CC_EXPORT ResourceProvider { DISALLOW_COPY_AND_ASSIGN(Fence); }; - // Acquire pixel buffer for resource. The pixel buffer can be used to - // set resource pixels without performing unnecessary copying. - void AcquirePixelBuffer(ResourceId id); - void ReleasePixelBuffer(ResourceId id); - - // Map/unmap the acquired pixel buffer. - uint8_t* MapPixelBuffer(ResourceId id); - void UnmapPixelBuffer(ResourceId id); + // Returns a canvas for direct rasterization. + // Call Unmap before the resource can be read or used for compositing. + // It is used for direct gpu rasterization. + SkCanvas* MapDirectRasterBuffer(ResourceId id); + void UnmapDirectRasterBuffer(ResourceId id); + + // Returns a canvas backed by an image buffer. + // Rasterizing to the canvas writes the content into the image buffer, + // which is internally bound to the underlying resource when read. + // Call Unmap before the resource can be read or used for compositing. + // It is used by ImageRasterWorkerPool. + SkCanvas* MapImageRasterBuffer(ResourceId id); + void UnmapImageRasterBuffer(ResourceId id); + + // Returns a canvas backed by pixel buffer. + // The pixel buffer needs to be uploaded to the underlying resource + // using BeginSetPixels before the resouce can be used for compositing. + // It is used by PixelRasterWorkerPool. + void AcquirePixelRasterBuffer(ResourceId id); + void ReleasePixelRasterBuffer(ResourceId id); + SkCanvas* MapPixelRasterBuffer(ResourceId id); + void UnmapPixelRasterBuffer(ResourceId id); // Asynchronously update pixels from acquired pixel buffer. void BeginSetPixels(ResourceId id); void ForceSetPixelsToComplete(ResourceId id); bool DidSetPixelsComplete(ResourceId id); - // Acquire and release an image. The image allows direct - // manipulation of texture memory. - void AcquireImage(ResourceId id); - void ReleaseImage(ResourceId id); - - // Maps the acquired image so that its pixels could be modified. - // Unmap is called when all pixels are set. - uint8_t* MapImage(ResourceId id); - void UnmapImage(ResourceId id); - - // Returns the stride for the image. - int GetImageStride(ResourceId id); - // For tests only! This prevents detecting uninitialized reads. // Use SetPixels or LockForWrite to allocate implicitly. void AllocateForTesting(ResourceId id); @@ -367,6 +371,10 @@ class CC_EXPORT ResourceProvider { static GLint GetActiveTextureUnit(gpu::gles2::GLES2Interface* gl); private: + class DirectRasterBuffer; + class ImageRasterBuffer; + class PixelRasterBuffer; + struct Resource { enum Origin { Internal, External, Delegated }; @@ -431,9 +439,98 @@ class CC_EXPORT ResourceProvider { bool has_shared_bitmap_id; SharedBitmapId shared_bitmap_id; SharedBitmap* shared_bitmap; + linked_ptr<DirectRasterBuffer> direct_raster_buffer; + linked_ptr<ImageRasterBuffer> image_raster_buffer; + linked_ptr<PixelRasterBuffer> pixel_raster_buffer; }; typedef base::hash_map<ResourceId, Resource> ResourceMap; + class RasterBuffer { + public: + virtual ~RasterBuffer(); + + SkCanvas* LockForWrite(); + void UnlockForWrite(); + + protected: + RasterBuffer(const Resource* resource, ResourceProvider* resource_provider); + const Resource* resource() const { return resource_; } + ResourceProvider* resource_provider() const { return resource_provider_; } + + virtual SkCanvas* DoLockForWrite() = 0; + virtual void DoUnlockForWrite() = 0; + + private: + const Resource* resource_; + ResourceProvider* resource_provider_; + SkCanvas* locked_canvas_; + int canvas_save_count_; + }; + + class DirectRasterBuffer : public RasterBuffer { + public: + DirectRasterBuffer(const Resource* resource, + ResourceProvider* resource_provider); + virtual ~DirectRasterBuffer(); + + protected: + virtual SkCanvas* DoLockForWrite() OVERRIDE; + virtual void DoUnlockForWrite() OVERRIDE; + skia::RefPtr<SkSurface> CreateSurface(); + + private: + skia::RefPtr<SkSurface> surface_; + DISALLOW_COPY_AND_ASSIGN(DirectRasterBuffer); + }; + + class BitmapRasterBuffer : public RasterBuffer { + public: + virtual ~BitmapRasterBuffer(); + + protected: + BitmapRasterBuffer(const Resource* resource, + ResourceProvider* resource_provider); + + virtual SkCanvas* DoLockForWrite() OVERRIDE; + virtual void DoUnlockForWrite() OVERRIDE; + + virtual uint8_t* MapBuffer(int* stride) = 0; + virtual void UnmapBuffer() = 0; + + private: + uint8_t* mapped_buffer_; + SkBitmap raster_bitmap_; + skia::RefPtr<SkCanvas> raster_canvas_; + }; + + class ImageRasterBuffer : public BitmapRasterBuffer { + public: + ImageRasterBuffer(const Resource* resource, + ResourceProvider* resource_provider); + virtual ~ImageRasterBuffer(); + + protected: + virtual uint8_t* MapBuffer(int* stride) OVERRIDE; + virtual void UnmapBuffer() OVERRIDE; + + private: + DISALLOW_COPY_AND_ASSIGN(ImageRasterBuffer); + }; + + class PixelRasterBuffer : public BitmapRasterBuffer { + public: + PixelRasterBuffer(const Resource* resource, + ResourceProvider* resource_provider); + virtual ~PixelRasterBuffer(); + + protected: + virtual uint8_t* MapBuffer(int* stride) OVERRIDE; + virtual void UnmapBuffer() OVERRIDE; + + private: + DISALLOW_COPY_AND_ASSIGN(PixelRasterBuffer); + }; + static bool CompareResourceMapIteratorsByChildId( const std::pair<ReturnedResource, ResourceMap::iterator>& a, const std::pair<ReturnedResource, ResourceMap::iterator>& b); @@ -450,7 +547,7 @@ class CC_EXPORT ResourceProvider { }; typedef base::hash_map<int, Child> ChildMap; - bool ReadLockFenceHasPassed(Resource* resource) { + bool ReadLockFenceHasPassed(const Resource* resource) { return !resource->read_lock_fence.get() || resource->read_lock_fence->HasPassed(); } @@ -485,8 +582,27 @@ class CC_EXPORT ResourceProvider { void DestroyChildInternal(ChildMap::iterator it, DeleteStyle style); void LazyCreate(Resource* resource); void LazyAllocate(Resource* resource); - void BindImageForSampling(Resource* resource); + // TODO(alokp): Move the implementation to PixelRasterBuffer. + // Acquire pixel buffer for resource. The pixel buffer can be used to + // set resource pixels without performing unnecessary copying. + void AcquirePixelBuffer(Resource* resource); + void ReleasePixelBuffer(Resource* resource); + // Map/unmap the acquired pixel buffer. + uint8_t* MapPixelBuffer(const Resource* resource, int* stride); + void UnmapPixelBuffer(const Resource* resource); + + // TODO(alokp): Move the implementation to ImageRasterBuffer. + // Acquire and release an image. The image allows direct + // manipulation of texture memory. + void AcquireImage(Resource* resource); + void ReleaseImage(Resource* resource); + // Maps the acquired image so that its pixels could be modified. + // Unmap is called when all pixels are set. + uint8_t* MapImage(const Resource* resource, int* stride); + void UnmapImage(const Resource* resource); + + void BindImageForSampling(Resource* resource); // Binds the given GL resource to a texture target for sampling using the // specified filter for both minification and magnification. Returns the // texture target used. The resource must be locked for reading. @@ -496,6 +612,7 @@ class CC_EXPORT ResourceProvider { // Returns NULL if the output_surface_ does not have a ContextProvider. gpu::gles2::GLES2Interface* ContextGL() const; + class GrContext* GrContext() const; OutputSurface* output_surface_; SharedBitmapManager* shared_bitmap_manager_; diff --git a/cc/resources/resource_provider_unittest.cc b/cc/resources/resource_provider_unittest.cc index 6286e58..07247c6 100644 --- a/cc/resources/resource_provider_unittest.cc +++ b/cc/resources/resource_provider_unittest.cc @@ -654,9 +654,8 @@ TEST_P(ResourceProviderTest, TransferGLResources) { ResourceProvider::ResourceId id3 = child_resource_provider_->CreateResource( size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format); - child_resource_provider_->AcquireImage(id3); - child_resource_provider_->MapImage(id3); - child_resource_provider_->UnmapImage(id3); + child_resource_provider_->MapImageRasterBuffer(id3); + child_resource_provider_->UnmapImageRasterBuffer(id3); GLuint external_texture_id = child_context_->createExternalTexture(); child_context_->bindTexture(GL_TEXTURE_EXTERNAL_OES, external_texture_id); @@ -895,11 +894,13 @@ TEST_P(ResourceProviderTest, TransferSoftwareResources) { ResourceProvider::ResourceId id3 = child_resource_provider_->CreateResource( size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format); - child_resource_provider_->AcquireImage(id3); - void* data = child_resource_provider_->MapImage(id3); uint8_t data3[4] = { 6, 7, 8, 9 }; - memcpy(data, data3, sizeof(data3)); - child_resource_provider_->UnmapImage(id3); + SkBitmap bitmap3; + bitmap3.setConfig(SkBitmap::kARGB_8888_Config, size.width(), size.height()); + bitmap3.setPixels(data3); + SkCanvas* raster_canvas = child_resource_provider_->MapImageRasterBuffer(id3); + raster_canvas->writePixels(bitmap3, 0, 0); + child_resource_provider_->UnmapImageRasterBuffer(id3); scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory()); shared_memory->CreateAndMapAnonymous(1); @@ -2616,7 +2617,7 @@ TEST_P(ResourceProviderTest, TextureAllocation) { // Same for async version. id = resource_provider->CreateResource( size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format); - resource_provider->AcquirePixelBuffer(id); + resource_provider->AcquirePixelRasterBuffer(id); EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id)); EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(2); @@ -2625,7 +2626,7 @@ TEST_P(ResourceProviderTest, TextureAllocation) { resource_provider->BeginSetPixels(id); ASSERT_TRUE(resource_provider->DidSetPixelsComplete(id)); - resource_provider->ReleasePixelBuffer(id); + resource_provider->ReleasePixelRasterBuffer(id); EXPECT_CALL(*context, RetireTextureId(texture_id)).Times(1); resource_provider->DeleteResource(id); @@ -2732,7 +2733,7 @@ TEST_P(ResourceProviderTest, PixelBuffer_GLTexture) { id = resource_provider->CreateResource( size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format); - resource_provider->AcquirePixelBuffer(id); + resource_provider->AcquirePixelRasterBuffer(id); EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id)); EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(2); @@ -2742,7 +2743,7 @@ TEST_P(ResourceProviderTest, PixelBuffer_GLTexture) { EXPECT_TRUE(resource_provider->DidSetPixelsComplete(id)); - resource_provider->ReleasePixelBuffer(id); + resource_provider->ReleasePixelRasterBuffer(id); EXPECT_CALL(*context, RetireTextureId(texture_id)).Times(1); resource_provider->DeleteResource(id); @@ -2769,17 +2770,20 @@ TEST_P(ResourceProviderTest, PixelBuffer_Bitmap) { id = resource_provider->CreateResource( size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format); - resource_provider->AcquirePixelBuffer(id); + resource_provider->AcquirePixelRasterBuffer(id); - void* data = resource_provider->MapPixelBuffer(id); - ASSERT_TRUE(!!data); - memcpy(data, &kBadBeef, sizeof(kBadBeef)); - resource_provider->UnmapPixelBuffer(id); + SkBitmap bitmap; + bitmap.setConfig(SkBitmap::kARGB_8888_Config, size.width(), size.height()); + bitmap.allocPixels(); + *(bitmap.getAddr32(0, 0)) = kBadBeef; + SkCanvas* canvas = resource_provider->MapPixelRasterBuffer(id); + canvas->writePixels(bitmap, 0, 0); + resource_provider->UnmapPixelRasterBuffer(id); resource_provider->BeginSetPixels(id); EXPECT_TRUE(resource_provider->DidSetPixelsComplete(id)); - resource_provider->ReleasePixelBuffer(id); + resource_provider->ReleasePixelRasterBuffer(id); { ResourceProvider::ScopedReadLockSoftware lock(resource_provider.get(), id); @@ -2815,7 +2819,7 @@ TEST_P(ResourceProviderTest, ForcingAsyncUploadToComplete) { id = resource_provider->CreateResource( size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format); - resource_provider->AcquirePixelBuffer(id); + resource_provider->AcquirePixelRasterBuffer(id); EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id)); EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(2); @@ -2828,7 +2832,7 @@ TEST_P(ResourceProviderTest, ForcingAsyncUploadToComplete) { EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, 0)).Times(1); resource_provider->ForceSetPixelsToComplete(id); - resource_provider->ReleasePixelBuffer(id); + resource_provider->ReleasePixelRasterBuffer(id); EXPECT_CALL(*context, RetireTextureId(texture_id)).Times(1); resource_provider->DeleteResource(id); @@ -2860,11 +2864,12 @@ TEST_P(ResourceProviderTest, PixelBufferLostContext) { size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format); context->loseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB); - resource_provider->AcquirePixelBuffer(id); - uint8_t* buffer = resource_provider->MapPixelBuffer(id); - EXPECT_TRUE(buffer == NULL); - resource_provider->UnmapPixelBuffer(id); - resource_provider->ReleasePixelBuffer(id); + + resource_provider->AcquirePixelRasterBuffer(id); + SkCanvas* raster_canvas = resource_provider->MapPixelRasterBuffer(id); + EXPECT_TRUE(raster_canvas == NULL); + resource_provider->UnmapPixelRasterBuffer(id); + resource_provider->ReleasePixelRasterBuffer(id); Mock::VerifyAndClearExpectations(context); } @@ -2894,30 +2899,26 @@ TEST_P(ResourceProviderTest, Image_GLTexture) { id = resource_provider->CreateResource( size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format); - EXPECT_CALL(*context, createImageCHROMIUM(kWidth, kHeight, GL_RGBA8_OES)) - .WillOnce(Return(kImageId)) - .RetiresOnSaturation(); - resource_provider->AcquireImage(id); + const int kStride = 4; void* dummy_mapped_buffer_address = NULL; - EXPECT_CALL(*context, mapImageCHROMIUM(kImageId, GL_READ_WRITE)) - .WillOnce(Return(dummy_mapped_buffer_address)) + EXPECT_CALL(*context, createImageCHROMIUM(kWidth, kHeight, GL_RGBA8_OES)) + .WillOnce(Return(kImageId)) .RetiresOnSaturation(); - resource_provider->MapImage(id); - - const int kStride = 4; EXPECT_CALL(*context, getImageParameterivCHROMIUM(kImageId, GL_IMAGE_ROWBYTES_CHROMIUM, _)) .WillOnce(SetArgPointee<2>(kStride)) .RetiresOnSaturation(); - int stride = resource_provider->GetImageStride(id); - EXPECT_EQ(kStride, stride); + EXPECT_CALL(*context, mapImageCHROMIUM(kImageId, GL_READ_WRITE)) + .WillOnce(Return(dummy_mapped_buffer_address)) + .RetiresOnSaturation(); + resource_provider->MapImageRasterBuffer(id); EXPECT_CALL(*context, unmapImageCHROMIUM(kImageId)) .Times(1) .RetiresOnSaturation(); - resource_provider->UnmapImage(id); + resource_provider->UnmapImageRasterBuffer(id); EXPECT_CALL(*context, NextTextureId()) .WillOnce(Return(kTextureId)) @@ -2934,15 +2935,20 @@ TEST_P(ResourceProviderTest, Image_GLTexture) { EXPECT_EQ(kTextureId, lock_gl.texture_id()); } + EXPECT_CALL( + *context, + getImageParameterivCHROMIUM(kImageId, GL_IMAGE_ROWBYTES_CHROMIUM, _)) + .WillOnce(SetArgPointee<2>(kStride)) + .RetiresOnSaturation(); EXPECT_CALL(*context, mapImageCHROMIUM(kImageId, GL_READ_WRITE)) .WillOnce(Return(dummy_mapped_buffer_address)) .RetiresOnSaturation(); - resource_provider->MapImage(id); + resource_provider->MapImageRasterBuffer(id); EXPECT_CALL(*context, unmapImageCHROMIUM(kImageId)) .Times(1) .RetiresOnSaturation(); - resource_provider->UnmapImage(id); + resource_provider->UnmapImageRasterBuffer(id); EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, kTextureId)).Times(1) .RetiresOnSaturation(); @@ -2964,7 +2970,6 @@ TEST_P(ResourceProviderTest, Image_GLTexture) { EXPECT_CALL(*context, destroyImageCHROMIUM(kImageId)) .Times(1) .RetiresOnSaturation(); - resource_provider->ReleaseImage(id); } TEST_P(ResourceProviderTest, Image_Bitmap) { @@ -2986,16 +2991,15 @@ TEST_P(ResourceProviderTest, Image_Bitmap) { id = resource_provider->CreateResource( size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureUsageAny, format); - resource_provider->AcquireImage(id); - - const int kStride = 0; - int stride = resource_provider->GetImageStride(id); - EXPECT_EQ(kStride, stride); - void* data = resource_provider->MapImage(id); - ASSERT_TRUE(!!data); - memcpy(data, &kBadBeef, sizeof(kBadBeef)); - resource_provider->UnmapImage(id); + SkBitmap bitmap; + bitmap.setConfig(SkBitmap::kARGB_8888_Config, size.width(), size.height()); + bitmap.allocPixels(); + *(bitmap.getAddr32(0, 0)) = kBadBeef; + SkCanvas* canvas = resource_provider->MapImageRasterBuffer(id); + ASSERT_TRUE(!!canvas); + canvas->writePixels(bitmap, 0, 0); + resource_provider->UnmapImageRasterBuffer(id); { ResourceProvider::ScopedReadLockSoftware lock(resource_provider.get(), id); @@ -3005,7 +3009,6 @@ TEST_P(ResourceProviderTest, Image_Bitmap) { EXPECT_EQ(*sk_bitmap->getAddr32(0, 0), kBadBeef); } - resource_provider->ReleaseImage(id); resource_provider->DeleteResource(id); } diff --git a/cc/test/fake_tile_manager.cc b/cc/test/fake_tile_manager.cc index d6e9836..1d6ecd8 100644 --- a/cc/test/fake_tile_manager.cc +++ b/cc/test/fake_tile_manager.cc @@ -57,8 +57,8 @@ class FakeRasterWorkerPool : public RasterWorkerPool { } // Overridden from internal::WorkerPoolTaskClient: - virtual void* AcquireBufferForRaster(internal::RasterWorkerPoolTask* task, - int* stride) OVERRIDE { + virtual SkCanvas* AcquireCanvasForRaster(internal::RasterWorkerPoolTask* task) + OVERRIDE { return NULL; } virtual void OnRasterCompleted(internal::RasterWorkerPoolTask* task, |