Index: cc/resources/resource_provider.cc |
diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc |
index 04581d5a95b60a7a77304fef00975b316650b7e2..207b7626441bb0f06b443f481fbc73fff6475743 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,21 @@ 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 ScopedSetActiveTexture { |
public: |
ScopedSetActiveTexture(GLES2Interface* gl, GLenum unit) |
@@ -281,6 +299,167 @@ ResourceProvider::Resource::Resource(uint8_t* pixels, |
DCHECK(origin == Delegated || pixels); |
} |
+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_->save(); |
+ return locked_canvas_; |
+} |
+ |
+void ResourceProvider::RasterBuffer::UnlockForWrite() { |
+ DCHECK(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_->getCanvas(); |
+} |
+ |
+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(); |
+ 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), buffer_(NULL) {} |
+ |
+ResourceProvider::BitmapRasterBuffer::~BitmapRasterBuffer() {} |
+ |
+SkCanvas* ResourceProvider::BitmapRasterBuffer::DoLockForWrite() { |
+ DCHECK(!buffer_); |
+ DCHECK(!canvas_); |
+ |
+ int stride = 0; |
+ buffer_ = MapBuffer(&stride); |
+ 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, |
+ resource()->size.width(), |
+ resource()->size.height()); |
+ bitmap.allocPixels(); |
+ break; |
+ case RGBA_8888: |
+ case BGRA_8888: |
+ bitmap.setConfig(SkBitmap::kARGB_8888_Config, |
+ resource()->size.width(), |
+ resource()->size.height(), |
+ stride); |
+ bitmap.setPixels(buffer_); |
+ break; |
+ case LUMINANCE_8: |
+ case RGB_565: |
+ case ETC1: |
+ NOTREACHED(); |
+ break; |
+ } |
+ skia::RefPtr<SkBitmapDevice> device = |
+ skia::AdoptRef(new SkBitmapDevice(bitmap)); |
+ canvas_ = skia::AdoptRef(new SkCanvas(device.get())); |
+ |
+ return canvas_.get(); |
+} |
+ |
+void ResourceProvider::BitmapRasterBuffer::DoUnlockForWrite() { |
+ canvas_.clear(); |
+ |
+ UnmapBuffer(); |
+ 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() {} |
@@ -538,6 +717,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(); |
@@ -1425,8 +1608,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); |
@@ -1455,8 +1694,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); |
@@ -1470,7 +1708,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) { |
@@ -1492,12 +1730,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); |
@@ -1515,8 +1754,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); |
@@ -1768,8 +2006,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); |
@@ -1789,8 +2026,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); |
@@ -1806,8 +2042,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); |
@@ -1816,15 +2051,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); |
@@ -1832,25 +2069,7 @@ 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) { |
@@ -1864,4 +2083,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 |