summaryrefslogtreecommitdiffstats
path: root/chromium/cc/resources/resource_provider.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/cc/resources/resource_provider.cc')
-rw-r--r--chromium/cc/resources/resource_provider.cc1192
1 files changed, 833 insertions, 359 deletions
diff --git a/chromium/cc/resources/resource_provider.cc b/chromium/cc/resources/resource_provider.cc
index 1331ca2f1cf..e3c21ff7c6b 100644
--- a/chromium/cc/resources/resource_provider.cc
+++ b/chromium/cc/resources/resource_provider.cc
@@ -17,12 +17,15 @@
#include "cc/resources/platform_color.h"
#include "cc/resources/returned_resource.h"
#include "cc/resources/shared_bitmap_manager.h"
+#include "cc/resources/texture_uploader.h"
#include "cc/resources/transferable_resource.h"
-#include "cc/scheduler/texture_uploader.h"
#include "gpu/GLES2/gl2extchromium.h"
#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,42 @@ 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, SkColorType dst_colorType) {
+ SkBitmap dst_bitmap;
+ IdentityAllocator allocator(dst);
+ src.copyTo(&dst_bitmap, dst_colorType, &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)
@@ -159,6 +198,30 @@ class BufferIdAllocator : public IdAllocator {
DISALLOW_COPY_AND_ASSIGN(BufferIdAllocator);
};
+// Generic fence implementation for query objects. Fence has passed when query
+// result is available.
+class QueryFence : public ResourceProvider::Fence {
+ public:
+ QueryFence(gpu::gles2::GLES2Interface* gl, unsigned query_id)
+ : gl_(gl), query_id_(query_id) {}
+
+ // Overridden from ResourceProvider::Fence:
+ virtual bool HasPassed() OVERRIDE {
+ unsigned available = 1;
+ gl_->GetQueryObjectuivEXT(
+ query_id_, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
+ return !!available;
+ }
+
+ private:
+ virtual ~QueryFence() {}
+
+ gpu::gles2::GLES2Interface* gl_;
+ unsigned query_id_;
+
+ DISALLOW_COPY_AND_ASSIGN(QueryFence);
+};
+
} // namespace
ResourceProvider::Resource::Resource()
@@ -166,38 +229,41 @@ ResourceProvider::Resource::Resource()
gl_id(0),
gl_pixel_buffer_id(0),
gl_upload_query_id(0),
+ gl_read_lock_query_id(0),
pixels(NULL),
- pixel_buffer(NULL),
lock_for_read_count(0),
imported_count(0),
exported_count(0),
+ dirty_image(false),
locked_for_write(false),
- external(false),
+ lost(false),
marked_for_deletion(false),
pending_set_pixels(false),
set_pixels_completion_forced(false),
allocated(false),
enable_read_lock_fences(false),
+ has_shared_bitmap_id(false),
+ allow_overlay(false),
read_lock_fence(NULL),
size(),
+ origin(Internal),
target(0),
original_filter(0),
filter(0),
image_id(0),
bound_image_id(0),
- dirty_image(false),
texture_pool(0),
wrap_mode(0),
- lost(false),
hint(TextureUsageAny),
- type(static_cast<ResourceType>(0)),
+ type(InvalidType),
format(RGBA_8888),
shared_bitmap(NULL) {}
ResourceProvider::Resource::~Resource() {}
ResourceProvider::Resource::Resource(GLuint texture_id,
- gfx::Size size,
+ const gfx::Size& size,
+ Origin origin,
GLenum target,
GLenum filter,
GLenum texture_pool,
@@ -208,73 +274,319 @@ ResourceProvider::Resource::Resource(GLuint texture_id,
gl_id(texture_id),
gl_pixel_buffer_id(0),
gl_upload_query_id(0),
+ gl_read_lock_query_id(0),
pixels(NULL),
- pixel_buffer(NULL),
lock_for_read_count(0),
imported_count(0),
exported_count(0),
+ dirty_image(false),
locked_for_write(false),
- external(false),
+ lost(false),
marked_for_deletion(false),
pending_set_pixels(false),
set_pixels_completion_forced(false),
allocated(false),
enable_read_lock_fences(false),
+ has_shared_bitmap_id(false),
+ allow_overlay(false),
read_lock_fence(NULL),
size(size),
+ origin(origin),
target(target),
original_filter(filter),
filter(filter),
image_id(0),
bound_image_id(0),
- dirty_image(false),
texture_pool(texture_pool),
wrap_mode(wrap_mode),
- lost(false),
hint(hint),
type(GLTexture),
format(format),
shared_bitmap(NULL) {
DCHECK(wrap_mode == GL_CLAMP_TO_EDGE || wrap_mode == GL_REPEAT);
+ DCHECK_EQ(origin == Internal, !!texture_pool);
}
ResourceProvider::Resource::Resource(uint8_t* pixels,
SharedBitmap* bitmap,
- gfx::Size size,
+ const gfx::Size& size,
+ Origin origin,
GLenum filter,
GLint wrap_mode)
: child_id(0),
gl_id(0),
gl_pixel_buffer_id(0),
gl_upload_query_id(0),
+ gl_read_lock_query_id(0),
pixels(pixels),
- pixel_buffer(NULL),
lock_for_read_count(0),
imported_count(0),
exported_count(0),
+ dirty_image(false),
locked_for_write(false),
- external(false),
+ lost(false),
marked_for_deletion(false),
pending_set_pixels(false),
set_pixels_completion_forced(false),
allocated(false),
enable_read_lock_fences(false),
+ has_shared_bitmap_id(!!bitmap),
+ allow_overlay(false),
read_lock_fence(NULL),
size(size),
+ origin(origin),
target(0),
original_filter(filter),
filter(filter),
image_id(0),
bound_image_id(0),
- dirty_image(false),
texture_pool(0),
wrap_mode(wrap_mode),
- lost(false),
hint(TextureUsageAny),
type(Bitmap),
format(RGBA_8888),
shared_bitmap(bitmap) {
DCHECK(wrap_mode == GL_CLAMP_TO_EDGE || wrap_mode == GL_REPEAT);
+ DCHECK(origin == Delegated || pixels);
+ if (bitmap)
+ shared_bitmap_id = bitmap->id();
+}
+
+ResourceProvider::Resource::Resource(const SharedBitmapId& bitmap_id,
+ const gfx::Size& size,
+ Origin origin,
+ GLenum filter,
+ GLint wrap_mode)
+ : child_id(0),
+ gl_id(0),
+ gl_pixel_buffer_id(0),
+ gl_upload_query_id(0),
+ gl_read_lock_query_id(0),
+ pixels(NULL),
+ lock_for_read_count(0),
+ imported_count(0),
+ exported_count(0),
+ dirty_image(false),
+ locked_for_write(false),
+ lost(false),
+ marked_for_deletion(false),
+ pending_set_pixels(false),
+ set_pixels_completion_forced(false),
+ allocated(false),
+ enable_read_lock_fences(false),
+ has_shared_bitmap_id(true),
+ allow_overlay(false),
+ read_lock_fence(NULL),
+ size(size),
+ origin(origin),
+ target(0),
+ original_filter(filter),
+ filter(filter),
+ image_id(0),
+ bound_image_id(0),
+ texture_pool(0),
+ wrap_mode(wrap_mode),
+ hint(TextureUsageAny),
+ type(Bitmap),
+ format(RGBA_8888),
+ shared_bitmap_id(bitmap_id),
+ shared_bitmap(NULL) {
+ 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() {
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
+ "ResourceProvider::RasterBuffer::LockForWrite");
+
+ DCHECK(!locked_canvas_);
+
+ locked_canvas_ = DoLockForWrite();
+ canvas_save_count_ = locked_canvas_ ? locked_canvas_->save() : 0;
+ return locked_canvas_;
+}
+
+bool ResourceProvider::RasterBuffer::UnlockForWrite() {
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
+ "ResourceProvider::RasterBuffer::UnlockForWrite");
+
+ if (locked_canvas_) {
+ locked_canvas_->restoreToCount(canvas_save_count_);
+ locked_canvas_ = NULL;
+ }
+ return DoUnlockForWrite();
+}
+
+ResourceProvider::DirectRasterBuffer::DirectRasterBuffer(
+ const Resource* resource,
+ ResourceProvider* resource_provider,
+ bool use_distance_field_text )
+ : RasterBuffer(resource, resource_provider),
+ surface_generation_id_(0u),
+ use_distance_field_text_(use_distance_field_text) {}
+
+ResourceProvider::DirectRasterBuffer::~DirectRasterBuffer() {}
+
+SkCanvas* ResourceProvider::DirectRasterBuffer::DoLockForWrite() {
+ if (!surface_)
+ surface_ = CreateSurface();
+ surface_generation_id_ = surface_ ? surface_->generationID() : 0u;
+ return surface_ ? surface_->getCanvas() : NULL;
+}
+
+bool ResourceProvider::DirectRasterBuffer::DoUnlockForWrite() {
+ // generationID returns a non-zero, unique value corresponding to the content
+ // of surface. Hence, a change since DoLockForWrite was called means the
+ // surface has changed.
+ return surface_ ? surface_generation_id_ != surface_->generationID() : false;
+}
+
+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));
+ SkSurface::TextRenderMode text_render_mode =
+ use_distance_field_text_ ? SkSurface::kDistanceField_TextRenderMode
+ : SkSurface::kStandard_TextRenderMode;
+ surface = skia::AdoptRef(SkSurface::NewRenderTargetDirect(
+ gr_texture->asRenderTarget(), text_render_mode));
+ }
+ break;
+ }
+ case Bitmap: {
+ DCHECK(resource()->pixels);
+ DCHECK_EQ(RGBA_8888, resource()->format);
+ SkImageInfo image_info = SkImageInfo::MakeN32Premul(
+ resource()->size.width(), resource()->size.height());
+ surface = skia::AdoptRef(SkSurface::NewRasterDirect(
+ image_info, resource()->pixels, image_info.minRowBytes()));
+ break;
+ }
+ default:
+ NOTREACHED();
+ }
+ return surface;
+}
+
+ResourceProvider::BitmapRasterBuffer::BitmapRasterBuffer(
+ const Resource* resource,
+ ResourceProvider* resource_provider)
+ : RasterBuffer(resource, resource_provider),
+ mapped_buffer_(NULL),
+ raster_bitmap_generation_id_(0u) {}
+
+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_.allocN32Pixels(resource()->size.width(),
+ resource()->size.height());
+ break;
+ case RGBA_8888:
+ case BGRA_8888: {
+ SkImageInfo info = SkImageInfo::MakeN32Premul(resource()->size.width(),
+ resource()->size.height());
+ if (0 == stride)
+ stride = info.minRowBytes();
+ raster_bitmap_.installPixels(info, mapped_buffer_, stride);
+ break;
+ }
+ case LUMINANCE_8:
+ case RGB_565:
+ case ETC1:
+ NOTREACHED();
+ break;
+ }
+ raster_canvas_ = skia::AdoptRef(new SkCanvas(raster_bitmap_));
+ raster_bitmap_generation_id_ = raster_bitmap_.getGenerationID();
+ return raster_canvas_.get();
+}
+
+bool ResourceProvider::BitmapRasterBuffer::DoUnlockForWrite() {
+ raster_canvas_.clear();
+
+ // getGenerationID returns a non-zero, unique value corresponding to the
+ // pixels in bitmap. Hence, a change since DoLockForWrite was called means the
+ // bitmap has changed.
+ bool raster_bitmap_changed =
+ raster_bitmap_generation_id_ != raster_bitmap_.getGenerationID();
+
+ if (raster_bitmap_changed) {
+ SkColorType buffer_colorType =
+ ResourceFormatToSkColorType(resource()->format);
+ if (mapped_buffer_ && (buffer_colorType != raster_bitmap_.colorType()))
+ CopyBitmap(raster_bitmap_, mapped_buffer_, buffer_colorType);
+ }
+ raster_bitmap_.reset();
+
+ UnmapBuffer();
+ mapped_buffer_ = NULL;
+ return raster_bitmap_changed;
+}
+
+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) {}
@@ -286,24 +598,20 @@ scoped_ptr<ResourceProvider> ResourceProvider::Create(
SharedBitmapManager* shared_bitmap_manager,
int highp_threshold_min,
bool use_rgba_4444_texture_format,
- size_t id_allocation_chunk_size) {
+ size_t id_allocation_chunk_size,
+ bool use_distance_field_text) {
scoped_ptr<ResourceProvider> resource_provider(
new ResourceProvider(output_surface,
shared_bitmap_manager,
highp_threshold_min,
use_rgba_4444_texture_format,
- id_allocation_chunk_size));
+ id_allocation_chunk_size,
+ use_distance_field_text));
- bool success = false;
- if (resource_provider->ContextGL()) {
- success = resource_provider->InitializeGL();
- } else {
+ if (resource_provider->ContextGL())
+ resource_provider->InitializeGL();
+ else
resource_provider->InitializeSoftware();
- success = true;
- }
-
- if (!success)
- return scoped_ptr<ResourceProvider>();
DCHECK_NE(InvalidType, resource_provider->default_resource_type());
return resource_provider.Pass();
@@ -329,8 +637,13 @@ bool ResourceProvider::IsLost(ResourceId id) {
return resource->lost;
}
+bool ResourceProvider::AllowOverlay(ResourceId id) {
+ Resource* resource = GetResource(id);
+ return resource->allow_overlay;
+}
+
ResourceProvider::ResourceId ResourceProvider::CreateResource(
- gfx::Size size,
+ const gfx::Size& size,
GLint wrap_mode,
TextureUsageHint hint,
ResourceFormat format) {
@@ -355,7 +668,7 @@ ResourceProvider::ResourceId ResourceProvider::CreateResource(
}
ResourceProvider::ResourceId ResourceProvider::CreateManagedResource(
- gfx::Size size,
+ const gfx::Size& size,
GLenum target,
GLint wrap_mode,
TextureUsageHint hint,
@@ -381,7 +694,7 @@ ResourceProvider::ResourceId ResourceProvider::CreateManagedResource(
}
ResourceProvider::ResourceId ResourceProvider::CreateGLTexture(
- gfx::Size size,
+ const gfx::Size& size,
GLenum target,
GLenum texture_pool,
GLint wrap_mode,
@@ -392,15 +705,22 @@ ResourceProvider::ResourceId ResourceProvider::CreateGLTexture(
DCHECK(thread_checker_.CalledOnValidThread());
ResourceId id = next_id_++;
- Resource resource(
- 0, size, target, GL_LINEAR, texture_pool, wrap_mode, hint, format);
+ Resource resource(0,
+ size,
+ Resource::Internal,
+ target,
+ GL_LINEAR,
+ texture_pool,
+ wrap_mode,
+ hint,
+ format);
resource.allocated = false;
resources_[id] = resource;
return id;
}
ResourceProvider::ResourceId ResourceProvider::CreateBitmap(
- gfx::Size size, GLint wrap_mode) {
+ const gfx::Size& size, GLint wrap_mode) {
DCHECK(thread_checker_.CalledOnValidThread());
scoped_ptr<SharedBitmap> bitmap;
@@ -408,45 +728,43 @@ ResourceProvider::ResourceId ResourceProvider::CreateBitmap(
bitmap = shared_bitmap_manager_->AllocateSharedBitmap(size);
uint8_t* pixels;
- if (bitmap)
+ if (bitmap) {
pixels = bitmap->pixels();
- else
- pixels = new uint8_t[4 * size.GetArea()];
+ } else {
+ size_t bytes = SharedBitmap::CheckedSizeInBytes(size);
+ pixels = new uint8_t[bytes];
+ }
+ DCHECK(pixels);
ResourceId id = next_id_++;
Resource resource(
- pixels, bitmap.release(), size, GL_LINEAR, wrap_mode);
+ pixels, bitmap.release(), size, Resource::Internal, GL_LINEAR, wrap_mode);
resource.allocated = true;
resources_[id] = resource;
return id;
}
-ResourceProvider::ResourceId
-ResourceProvider::CreateResourceFromExternalTexture(
- GLuint texture_target,
- GLuint texture_id) {
+ResourceProvider::ResourceId ResourceProvider::CreateResourceFromIOSurface(
+ const gfx::Size& size,
+ unsigned io_surface_id) {
DCHECK(thread_checker_.CalledOnValidThread());
- GLES2Interface* gl = ContextGL();
- DCHECK(gl);
- GLC(gl, gl->BindTexture(texture_target, texture_id));
- GLC(gl, gl->TexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
- GLC(gl, gl->TexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
- GLC(gl,
- gl->TexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
- GLC(gl,
- gl->TexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
-
ResourceId id = next_id_++;
- Resource resource(texture_id,
+ Resource resource(0,
gfx::Size(),
- texture_target,
+ Resource::Internal,
+ GL_TEXTURE_RECTANGLE_ARB,
GL_LINEAR,
- 0,
+ GL_TEXTURE_POOL_UNMANAGED_CHROMIUM,
GL_CLAMP_TO_EDGE,
TextureUsageAny,
RGBA_8888);
- resource.external = true;
+ LazyCreate(&resource);
+ GLES2Interface* gl = ContextGL();
+ DCHECK(gl);
+ gl->BindTexture(GL_TEXTURE_RECTANGLE_ARB, resource.gl_id);
+ gl->TexImageIOSurface2DCHROMIUM(
+ GL_TEXTURE_RECTANGLE_ARB, size.width(), size.height(), io_surface_id, 0);
resource.allocated = true;
resources_[id] = resource;
return id;
@@ -463,6 +781,7 @@ ResourceProvider::ResourceId ResourceProvider::CreateResourceFromTextureMailbox(
if (mailbox.IsTexture()) {
resource = Resource(0,
gfx::Size(),
+ Resource::External,
mailbox.target(),
GL_LINEAR,
0,
@@ -474,6 +793,7 @@ ResourceProvider::ResourceId ResourceProvider::CreateResourceFromTextureMailbox(
base::SharedMemory* shared_memory = mailbox.shared_memory();
DCHECK(shared_memory->memory());
uint8_t* pixels = reinterpret_cast<uint8_t*>(shared_memory->memory());
+ DCHECK(pixels);
scoped_ptr<SharedBitmap> shared_bitmap;
if (shared_bitmap_manager_) {
shared_bitmap =
@@ -482,15 +802,16 @@ ResourceProvider::ResourceId ResourceProvider::CreateResourceFromTextureMailbox(
resource = Resource(pixels,
shared_bitmap.release(),
mailbox.shared_memory_size(),
+ Resource::External,
GL_LINEAR,
GL_CLAMP_TO_EDGE);
}
- resource.external = true;
resource.allocated = true;
resource.mailbox = mailbox;
resource.release_callback =
base::Bind(&SingleReleaseCallback::Run,
base::Owned(release_callback.release()));
+ resource.allow_overlay = mailbox.allow_overlay();
return id;
}
@@ -499,12 +820,11 @@ void ResourceProvider::DeleteResource(ResourceId id) {
ResourceMap::iterator it = resources_.find(id);
CHECK(it != resources_.end());
Resource* resource = &it->second;
- DCHECK(!resource->lock_for_read_count);
DCHECK(!resource->marked_for_deletion);
DCHECK_EQ(resource->imported_count, 0);
DCHECK(resource->pending_set_pixels || !resource->locked_for_write);
- if (resource->exported_count > 0) {
+ if (resource->exported_count > 0 || resource->lock_for_read_count > 0) {
resource->marked_for_deletion = true;
return;
} else {
@@ -522,37 +842,48 @@ 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();
DCHECK(gl);
GLC(gl, gl->DestroyImageCHROMIUM(resource->image_id));
}
-
- if (resource->gl_id && !resource->external) {
+ if (resource->gl_upload_query_id) {
+ DCHECK(resource->origin == Resource::Internal);
GLES2Interface* gl = ContextGL();
DCHECK(gl);
- GLC(gl, gl->DeleteTextures(1, &resource->gl_id));
+ GLC(gl, gl->DeleteQueriesEXT(1, &resource->gl_upload_query_id));
}
- if (resource->gl_upload_query_id) {
+ if (resource->gl_read_lock_query_id) {
+ DCHECK(resource->origin == Resource::Internal);
GLES2Interface* gl = ContextGL();
DCHECK(gl);
- GLC(gl, gl->DeleteQueriesEXT(1, &resource->gl_upload_query_id));
+ GLC(gl, gl->DeleteQueriesEXT(1, &resource->gl_read_lock_query_id));
}
if (resource->gl_pixel_buffer_id) {
+ DCHECK(resource->origin == Resource::Internal);
GLES2Interface* gl = ContextGL();
DCHECK(gl);
GLC(gl, gl->DeleteBuffers(1, &resource->gl_pixel_buffer_id));
}
- if (resource->mailbox.IsValid() && resource->external) {
+ if (resource->origin == Resource::External) {
+ DCHECK(resource->mailbox.IsValid());
GLuint sync_point = resource->mailbox.sync_point();
- if (resource->mailbox.IsTexture()) {
+ if (resource->type == GLTexture) {
+ DCHECK(resource->mailbox.IsTexture());
lost_resource |= lost_output_surface_;
GLES2Interface* gl = ContextGL();
DCHECK(gl);
- if (resource->gl_id)
+ if (resource->gl_id) {
GLC(gl, gl->DeleteTextures(1, &resource->gl_id));
- if (!lost_resource && resource->gl_id)
- sync_point = gl->InsertSyncPointCHROMIUM();
+ resource->gl_id = 0;
+ if (!lost_resource)
+ sync_point = gl->InsertSyncPointCHROMIUM();
+ }
} else {
DCHECK(resource->mailbox.IsSharedMemory());
base::SharedMemory* shared_memory = resource->mailbox.shared_memory();
@@ -565,15 +896,22 @@ void ResourceProvider::DeleteResourceInternal(ResourceMap::iterator it,
}
resource->release_callback.Run(sync_point, lost_resource);
}
+ if (resource->gl_id) {
+ GLES2Interface* gl = ContextGL();
+ DCHECK(gl);
+ GLC(gl, gl->DeleteTextures(1, &resource->gl_id));
+ resource->gl_id = 0;
+ }
if (resource->shared_bitmap) {
+ DCHECK(resource->origin != Resource::External);
+ DCHECK_EQ(Bitmap, resource->type);
delete resource->shared_bitmap;
resource->pixels = NULL;
}
- if (resource->pixels)
+ if (resource->pixels) {
+ DCHECK(resource->origin == Resource::Internal);
delete[] resource->pixels;
- if (resource->pixel_buffer)
- delete[] resource->pixel_buffer;
-
+ }
resources_.erase(it);
}
@@ -584,18 +922,19 @@ ResourceProvider::ResourceType ResourceProvider::GetResourceType(
void ResourceProvider::SetPixels(ResourceId id,
const uint8_t* image,
- gfx::Rect image_rect,
- gfx::Rect source_rect,
- gfx::Vector2d dest_offset) {
+ const gfx::Rect& image_rect,
+ const gfx::Rect& source_rect,
+ const gfx::Vector2d& dest_offset) {
Resource* resource = GetResource(id);
DCHECK(!resource->locked_for_write);
DCHECK(!resource->lock_for_read_count);
- DCHECK(!resource->external);
+ DCHECK(resource->origin == Resource::Internal);
DCHECK_EQ(resource->exported_count, 0);
DCHECK(ReadLockFenceHasPassed(resource));
LazyAllocate(resource);
- if (resource->gl_id) {
+ if (resource->type == GLTexture) {
+ DCHECK(resource->gl_id);
DCHECK(!resource->pending_set_pixels);
DCHECK_EQ(resource->target, static_cast<GLenum>(GL_TEXTURE_2D));
GLES2Interface* gl = ContextGL();
@@ -608,26 +947,24 @@ void ResourceProvider::SetPixels(ResourceId id,
dest_offset,
resource->format,
resource->size);
- }
-
- if (resource->pixels) {
+ } else {
+ DCHECK_EQ(Bitmap, resource->type);
DCHECK(resource->allocated);
DCHECK_EQ(RGBA_8888, resource->format);
- SkBitmap src_full;
- src_full.setConfig(
- SkBitmap::kARGB_8888_Config, image_rect.width(), image_rect.height());
- src_full.setPixels(const_cast<uint8_t*>(image));
- SkBitmap src_subset;
- SkIRect sk_source_rect = SkIRect::MakeXYWH(source_rect.x(),
- source_rect.y(),
- source_rect.width(),
- source_rect.height());
- sk_source_rect.offset(-image_rect.x(), -image_rect.y());
- src_full.extractSubset(&src_subset, sk_source_rect);
+ DCHECK(source_rect.x() >= image_rect.x());
+ DCHECK(source_rect.y() >= image_rect.y());
+ DCHECK(source_rect.right() <= image_rect.right());
+ DCHECK(source_rect.bottom() <= image_rect.bottom());
+ SkImageInfo source_info =
+ SkImageInfo::MakeN32Premul(source_rect.width(), source_rect.height());
+ size_t image_row_bytes = image_rect.width() * 4;
+ gfx::Vector2d source_offset = source_rect.origin() - image_rect.origin();
+ image += source_offset.y() * image_row_bytes + source_offset.x() * 4;
ScopedWriteLockSoftware lock(this, id);
SkCanvas* dest = lock.sk_canvas();
- dest->writePixels(src_subset, dest_offset.x(), dest_offset.y());
+ dest->writePixels(
+ source_info, image, image_row_bytes, dest_offset.x(), dest_offset.y());
}
}
@@ -733,19 +1070,30 @@ const ResourceProvider::Resource* ResourceProvider::LockForRead(ResourceId id) {
LazyCreate(resource);
- if (resource->external) {
- if (!resource->gl_id && resource->mailbox.IsTexture()) {
- GLES2Interface* gl = ContextGL();
- DCHECK(gl);
- if (resource->mailbox.sync_point()) {
- GLC(gl, gl->WaitSyncPointCHROMIUM(resource->mailbox.sync_point()));
- resource->mailbox.ResetSyncPoint();
- }
- resource->gl_id = texture_id_allocator_->NextId();
- GLC(gl, gl->BindTexture(resource->target, resource->gl_id));
- GLC(gl,
- gl->ConsumeTextureCHROMIUM(resource->target,
- resource->mailbox.data()));
+ if (resource->type == GLTexture && !resource->gl_id) {
+ DCHECK(resource->origin != Resource::Internal);
+ DCHECK(resource->mailbox.IsTexture());
+ GLES2Interface* gl = ContextGL();
+ DCHECK(gl);
+ if (resource->mailbox.sync_point()) {
+ GLC(gl, gl->WaitSyncPointCHROMIUM(resource->mailbox.sync_point()));
+ resource->mailbox.set_sync_point(0);
+ }
+ resource->gl_id = texture_id_allocator_->NextId();
+ GLC(gl, gl->BindTexture(resource->target, resource->gl_id));
+ GLC(gl,
+ gl->ConsumeTextureCHROMIUM(resource->mailbox.target(),
+ resource->mailbox.name()));
+ }
+
+ if (!resource->pixels && resource->has_shared_bitmap_id &&
+ shared_bitmap_manager_) {
+ scoped_ptr<SharedBitmap> bitmap =
+ shared_bitmap_manager_->GetSharedBitmapFromId(
+ resource->size, resource->shared_bitmap_id);
+ if (bitmap) {
+ resource->shared_bitmap = bitmap.release();
+ resource->pixels = resource->shared_bitmap->pixels();
}
}
@@ -757,10 +1105,25 @@ const ResourceProvider::Resource* ResourceProvider::LockForRead(ResourceId id) {
}
void ResourceProvider::UnlockForRead(ResourceId id) {
- Resource* resource = GetResource(id);
+ DCHECK(thread_checker_.CalledOnValidThread());
+ ResourceMap::iterator it = resources_.find(id);
+ CHECK(it != resources_.end());
+
+ Resource* resource = &it->second;
DCHECK_GT(resource->lock_for_read_count, 0);
DCHECK_EQ(resource->exported_count, 0);
resource->lock_for_read_count--;
+ if (resource->marked_for_deletion && !resource->lock_for_read_count) {
+ if (!resource->child_id) {
+ // The resource belongs to this ResourceProvider, so it can be destroyed.
+ DeleteResourceInternal(it, Normal);
+ } else {
+ ChildMap::iterator child_it = children_.find(resource->child_id);
+ ResourceIdArray unused;
+ unused.push_back(id);
+ DeleteAndReturnUnusedResourcesToChild(child_it, Normal, unused);
+ }
+ }
}
const ResourceProvider::Resource* ResourceProvider::LockForWrite(
@@ -769,7 +1132,7 @@ const ResourceProvider::Resource* ResourceProvider::LockForWrite(
DCHECK(!resource->locked_for_write);
DCHECK(!resource->lock_for_read_count);
DCHECK_EQ(resource->exported_count, 0);
- DCHECK(!resource->external);
+ DCHECK(resource->origin == Resource::Internal);
DCHECK(!resource->lost);
DCHECK(ReadLockFenceHasPassed(resource));
LazyAllocate(resource);
@@ -781,15 +1144,15 @@ const ResourceProvider::Resource* ResourceProvider::LockForWrite(
bool ResourceProvider::CanLockForWrite(ResourceId id) {
Resource* resource = GetResource(id);
return !resource->locked_for_write && !resource->lock_for_read_count &&
- !resource->exported_count && !resource->external && !resource->lost &&
- ReadLockFenceHasPassed(resource);
+ !resource->exported_count && resource->origin == Resource::Internal &&
+ !resource->lost && ReadLockFenceHasPassed(resource);
}
void ResourceProvider::UnlockForWrite(ResourceId id) {
Resource* resource = GetResource(id);
DCHECK(resource->locked_for_write);
DCHECK_EQ(resource->exported_count, 0);
- DCHECK(!resource->external);
+ DCHECK(resource->origin == Resource::Internal);
resource->locked_for_write = false;
}
@@ -843,12 +1206,10 @@ ResourceProvider::ScopedWriteLockGL::~ScopedWriteLockGL() {
void ResourceProvider::PopulateSkBitmapWithResource(
SkBitmap* sk_bitmap, const Resource* resource) {
- DCHECK(resource->pixels);
DCHECK_EQ(RGBA_8888, resource->format);
- sk_bitmap->setConfig(SkBitmap::kARGB_8888_Config,
- resource->size.width(),
- resource->size.height());
- sk_bitmap->setPixels(resource->pixels);
+ SkImageInfo info = SkImageInfo::MakeN32Premul(resource->size.width(),
+ resource->size.height());
+ sk_bitmap->installPixels(info, resource->pixels, info.minRowBytes());
}
ResourceProvider::ScopedReadLockSoftware::ScopedReadLockSoftware(
@@ -872,6 +1233,7 @@ ResourceProvider::ScopedWriteLockSoftware::ScopedWriteLockSoftware(
resource_id_(resource_id) {
ResourceProvider::PopulateSkBitmapWithResource(
&sk_bitmap_, resource_provider->LockForWrite(resource_id));
+ DCHECK(valid());
sk_canvas_.reset(new SkCanvas(sk_bitmap_));
}
@@ -883,7 +1245,8 @@ ResourceProvider::ResourceProvider(OutputSurface* output_surface,
SharedBitmapManager* shared_bitmap_manager,
int highp_threshold_min,
bool use_rgba_4444_texture_format,
- size_t id_allocation_chunk_size)
+ size_t id_allocation_chunk_size,
+ bool use_distance_field_text)
: output_surface_(output_surface),
shared_bitmap_manager_(shared_bitmap_manager),
lost_output_surface_(false),
@@ -897,7 +1260,9 @@ ResourceProvider::ResourceProvider(OutputSurface* output_surface,
max_texture_size_(0),
best_texture_format_(RGBA_8888),
use_rgba_4444_texture_format_(use_rgba_4444_texture_format),
- id_allocation_chunk_size_(id_allocation_chunk_size) {
+ id_allocation_chunk_size_(id_allocation_chunk_size),
+ use_sync_query_(false),
+ use_distance_field_text_(use_distance_field_text) {
DCHECK(output_surface_->HasClient());
DCHECK(id_allocation_chunk_size_);
}
@@ -914,7 +1279,7 @@ void ResourceProvider::InitializeSoftware() {
best_texture_format_ = RGBA_8888;
}
-bool ResourceProvider::InitializeGL() {
+void ResourceProvider::InitializeGL() {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(!texture_uploader_);
DCHECK_NE(GLTexture, default_resource_type_);
@@ -926,10 +1291,11 @@ bool ResourceProvider::InitializeGL() {
const ContextProvider::Capabilities& caps =
output_surface_->context_provider()->ContextCapabilities();
- bool use_bgra = caps.texture_format_bgra8888;
- use_texture_storage_ext_ = caps.texture_storage;
- use_texture_usage_hint_ = caps.texture_usage;
- use_compressed_texture_etc1_ = caps.texture_format_etc1;
+ bool use_bgra = caps.gpu.texture_format_bgra8888;
+ use_texture_storage_ext_ = caps.gpu.texture_storage;
+ use_texture_usage_hint_ = caps.gpu.texture_usage;
+ use_compressed_texture_etc1_ = caps.gpu.texture_format_etc1;
+ use_sync_query_ = caps.gpu.sync_query;
GLES2Interface* gl = ContextGL();
DCHECK(gl);
@@ -943,8 +1309,6 @@ bool ResourceProvider::InitializeGL() {
new TextureIdAllocator(gl, id_allocation_chunk_size_));
buffer_id_allocator_.reset(
new BufferIdAllocator(gl, id_allocation_chunk_size_));
-
- return true;
}
void ResourceProvider::CleanUpGLIfNeeded() {
@@ -957,6 +1321,15 @@ void ResourceProvider::CleanUpGLIfNeeded() {
}
DCHECK(gl);
+#if DCHECK_IS_ON
+ // Check that all GL resources has been deleted.
+ for (ResourceMap::const_iterator itr = resources_.begin();
+ itr != resources_.end();
+ ++itr) {
+ DCHECK_NE(GLTexture, itr->second.type);
+ }
+#endif // DCHECK_IS_ON
+
texture_uploader_.reset();
texture_id_allocator_.reset();
buffer_id_allocator_.reset();
@@ -1022,7 +1395,7 @@ void ResourceProvider::PrepareSendToParent(const ResourceIdArray& resources,
++it) {
TransferableResource resource;
TransferResource(gl, *it, &resource);
- if (!resource.sync_point && !resource.is_software)
+ if (!resource.mailbox_holder.sync_point && !resource.is_software)
need_sync_point = true;
++resources_.find(*it)->second.exported_count;
list->push_back(resource);
@@ -1032,8 +1405,8 @@ void ResourceProvider::PrepareSendToParent(const ResourceIdArray& resources,
for (TransferableResourceArray::iterator it = list->begin();
it != list->end();
++it) {
- if (!it->sync_point)
- it->sync_point = sync_point;
+ if (!it->mailbox_holder.sync_point)
+ it->mailbox_holder.sync_point = sync_point;
}
}
}
@@ -1050,21 +1423,14 @@ void ResourceProvider::ReceiveFromChild(
ResourceIdMap::iterator resource_in_map_it =
child_info.child_to_parent_map.find(it->id);
if (resource_in_map_it != child_info.child_to_parent_map.end()) {
- resources_[resource_in_map_it->second].imported_count++;
+ Resource& resource = resources_[resource_in_map_it->second];
+ resource.marked_for_deletion = false;
+ resource.imported_count++;
continue;
}
- scoped_ptr<SharedBitmap> bitmap;
- uint8_t* pixels = NULL;
- if (it->is_software) {
- if (shared_bitmap_manager_)
- bitmap = shared_bitmap_manager_->GetSharedBitmapFromId(it->size,
- it->mailbox);
- if (bitmap)
- pixels = bitmap->pixels();
- }
-
- if ((!it->is_software && !gl) || (it->is_software && !pixels)) {
+ if ((!it->is_software && !gl) ||
+ (it->is_software && !shared_bitmap_manager_)) {
TRACE_EVENT0("cc", "ResourceProvider::ReceiveFromChild dropping invalid");
ReturnedResourceArray to_return;
to_return.push_back(it->ToReturnedResource());
@@ -1075,30 +1441,24 @@ void ResourceProvider::ReceiveFromChild(
ResourceId local_id = next_id_++;
Resource& resource = resources_[local_id];
if (it->is_software) {
- resource = Resource(
- pixels, bitmap.release(), it->size, GL_LINEAR, GL_CLAMP_TO_EDGE);
+ resource = Resource(it->mailbox_holder.mailbox,
+ it->size,
+ Resource::Delegated,
+ GL_LINEAR,
+ it->is_repeated ? GL_REPEAT : GL_CLAMP_TO_EDGE);
} else {
- GLuint texture_id;
- // NOTE: If the parent is a browser and the child a renderer, the parent
- // is not supposed to have its context wait, because that could induce
- // deadlocks and/or security issues. The caller is responsible for
- // waiting asynchronously, and resetting sync_point before calling this.
- // However if the parent is a renderer (e.g. browser tag), it may be ok
- // (and is simpler) to wait.
- if (it->sync_point)
- GLC(gl, gl->WaitSyncPointCHROMIUM(it->sync_point));
- texture_id = texture_id_allocator_->NextId();
- GLC(gl, gl->BindTexture(it->target, texture_id));
- GLC(gl, gl->ConsumeTextureCHROMIUM(it->target, it->mailbox.name));
- resource = Resource(texture_id,
+ resource = Resource(0,
it->size,
- it->target,
+ Resource::Delegated,
+ it->mailbox_holder.texture_target,
it->filter,
0,
- GL_CLAMP_TO_EDGE,
+ it->is_repeated ? GL_REPEAT : GL_CLAMP_TO_EDGE,
TextureUsageAny,
it->format);
- resource.mailbox.SetName(it->mailbox);
+ resource.mailbox = TextureMailbox(it->mailbox_holder.mailbox,
+ it->mailbox_holder.texture_target,
+ it->mailbox_holder.sync_point);
}
resource.child_id = child;
// Don't allocate a texture for a child.
@@ -1126,6 +1486,7 @@ void ResourceProvider::DeclareUsedResourcesFromChild(
DCHECK(it != child_info.child_to_parent_map.end());
ResourceId local_id = it->second;
+ DCHECK(!resources_[local_id].marked_for_deletion);
child_info.in_use_resources.insert(local_id);
}
@@ -1195,12 +1556,20 @@ void ResourceProvider::ReceiveReturnsFromParent(
if (resource->exported_count)
continue;
- if (resource->gl_id) {
- if (returned.sync_point)
+ // Need to wait for the current read lock fence to pass before we can
+ // recycle this resource.
+ if (resource->enable_read_lock_fences)
+ resource->read_lock_fence = current_read_lock_fence_;
+
+ if (returned.sync_point) {
+ DCHECK(!resource->has_shared_bitmap_id);
+ if (resource->origin == Resource::Internal) {
+ DCHECK(resource->gl_id);
GLC(gl, gl->WaitSyncPointCHROMIUM(returned.sync_point));
- } else if (!resource->shared_bitmap) {
- resource->mailbox =
- TextureMailbox(resource->mailbox.name(), returned.sync_point);
+ } else {
+ DCHECK(!resource->gl_id);
+ resource->mailbox.set_sync_point(returned.sync_point);
+ }
}
if (!resource->marked_for_deletion)
@@ -1212,6 +1581,7 @@ void ResourceProvider::ReceiveReturnsFromParent(
continue;
}
+ DCHECK(resource->origin == Resource::Delegated);
// Delete the resource and return it to the child it came from one.
if (resource->child_id != child_id) {
if (child_id) {
@@ -1243,34 +1613,52 @@ void ResourceProvider::TransferResource(GLES2Interface* gl,
Resource* source = GetResource(id);
DCHECK(!source->locked_for_write);
DCHECK(!source->lock_for_read_count);
- DCHECK(!source->external || (source->external && source->mailbox.IsValid()));
+ DCHECK(source->origin != Resource::External || source->mailbox.IsValid());
DCHECK(source->allocated);
- DCHECK_EQ(source->wrap_mode, GL_CLAMP_TO_EDGE);
resource->id = id;
resource->format = source->format;
- resource->target = source->target;
+ resource->mailbox_holder.texture_target = source->target;
resource->filter = source->filter;
resource->size = source->size;
+ resource->is_repeated = (source->wrap_mode == GL_REPEAT);
- if (source->shared_bitmap) {
- resource->mailbox = source->shared_bitmap->id();
+ if (source->type == Bitmap) {
+ resource->mailbox_holder.mailbox = source->shared_bitmap_id;
resource->is_software = true;
} else if (!source->mailbox.IsValid()) {
+ LazyCreate(source);
+ DCHECK(source->gl_id);
+ DCHECK(source->origin == Resource::Internal);
+ GLC(gl,
+ gl->BindTexture(resource->mailbox_holder.texture_target,
+ source->gl_id));
+ if (source->image_id) {
+ DCHECK(source->dirty_image);
+ BindImageForSampling(source);
+ }
// This is a resource allocated by the compositor, we need to produce it.
// Don't set a sync point, the caller will do it.
- DCHECK(source->gl_id);
- GLC(gl, gl->BindTexture(resource->target, source->gl_id));
- GLC(gl, gl->GenMailboxCHROMIUM(resource->mailbox.name));
+ GLC(gl, gl->GenMailboxCHROMIUM(resource->mailbox_holder.mailbox.name));
GLC(gl,
- gl->ProduceTextureCHROMIUM(resource->target, resource->mailbox.name));
- source->mailbox.SetName(resource->mailbox);
+ gl->ProduceTextureCHROMIUM(resource->mailbox_holder.texture_target,
+ resource->mailbox_holder.mailbox.name));
+ source->mailbox = TextureMailbox(resource->mailbox_holder);
} else {
DCHECK(source->mailbox.IsTexture());
+ if (source->image_id && source->dirty_image) {
+ DCHECK(source->gl_id);
+ DCHECK(source->origin == Resource::Internal);
+ GLC(gl,
+ gl->BindTexture(resource->mailbox_holder.texture_target,
+ source->gl_id));
+ BindImageForSampling(source);
+ }
// This is either an external resource, or a compositor resource that we
// already exported. Make sure to forward the sync point that we were given.
- resource->mailbox = source->mailbox.name();
- resource->sync_point = source->mailbox.sync_point();
- source->mailbox.ResetSyncPoint();
+ resource->mailbox_holder.mailbox = source->mailbox.mailbox();
+ resource->mailbox_holder.texture_target = source->mailbox.target();
+ resource->mailbox_holder.sync_point = source->mailbox.sync_point();
+ source->mailbox.set_sync_point(0);
}
}
@@ -1297,7 +1685,6 @@ void ResourceProvider::DeleteAndReturnUnusedResourcesToChild(
Resource& resource = it->second;
DCHECK(!resource.locked_for_write);
- DCHECK(!resource.lock_for_read_count);
DCHECK_EQ(0u, child_info->in_use_resources.count(local_id));
DCHECK(child_info->parent_to_child_map.count(local_id));
@@ -1305,10 +1692,11 @@ void ResourceProvider::DeleteAndReturnUnusedResourcesToChild(
DCHECK(child_info->child_to_parent_map.count(child_id));
bool is_lost =
- resource.lost || (!resource.shared_bitmap && lost_output_surface_);
- if (resource.exported_count > 0) {
+ resource.lost || (resource.type == GLTexture && lost_output_surface_);
+ if (resource.exported_count > 0 || resource.lock_for_read_count > 0) {
if (style != ForShutdown) {
- // Defer this until we receive the resource back from the parent.
+ // Defer this until we receive the resource back from the parent or
+ // the read lock is released.
resource.marked_for_deletion = true;
continue;
}
@@ -1335,7 +1723,7 @@ void ResourceProvider::DeleteAndReturnUnusedResourcesToChild(
ReturnedResource returned;
returned.id = child_id;
returned.sync_point = resource.mailbox.sync_point();
- if (!returned.sync_point && !resource.shared_bitmap)
+ if (!returned.sync_point && resource.type == GLTexture)
need_sync_point = true;
returned.count = resource.imported_count;
returned.lost = is_lost;
@@ -1365,40 +1753,93 @@ 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);
- DCHECK(!resource->external);
- DCHECK_EQ(resource->exported_count, 0);
- DCHECK(!resource->image_id);
- DCHECK_NE(ETC1, resource->format);
-
- if (resource->type == GLTexture) {
- GLES2Interface* gl = ContextGL();
- DCHECK(gl);
- if (!resource->gl_pixel_buffer_id)
- resource->gl_pixel_buffer_id = buffer_id_allocator_->NextId();
- gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
- resource->gl_pixel_buffer_id);
- unsigned bytes_per_pixel = BitsPerPixel(resource->format) / 8;
- gl->BufferData(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
- resource->size.height() *
- RoundUp(bytes_per_pixel * resource->size.width(), 4u),
- NULL,
- GL_DYNAMIC_DRAW);
- gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
+ if (!resource->direct_raster_buffer.get()) {
+ resource->direct_raster_buffer.reset(
+ new DirectRasterBuffer(resource, this, use_distance_field_text_));
}
+ return resource->direct_raster_buffer->LockForWrite();
+}
- if (resource->pixels) {
- if (resource->pixel_buffer)
- return;
+void ResourceProvider::UnmapDirectRasterBuffer(ResourceId id) {
+ Resource* resource = GetResource(id);
+ DCHECK(resource->direct_raster_buffer.get());
+ resource->direct_raster_buffer->UnlockForWrite();
+ UnlockForWrite(id);
+}
- resource->pixel_buffer = new uint8_t[4 * resource->size.GetArea()];
- }
+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();
+}
+
+bool ResourceProvider::UnmapImageRasterBuffer(ResourceId id) {
+ Resource* resource = GetResource(id);
+ resource->dirty_image = true;
+ return resource->image_raster_buffer->UnlockForWrite();
}
-void ResourceProvider::ReleasePixelBuffer(ResourceId id) {
+void ResourceProvider::AcquirePixelRasterBuffer(ResourceId id) {
Resource* resource = GetResource(id);
- DCHECK(!resource->external);
+ 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();
+}
+
+bool ResourceProvider::UnmapPixelRasterBuffer(ResourceId id) {
+ Resource* resource = GetResource(id);
+ DCHECK(resource->pixel_raster_buffer.get());
+ return resource->pixel_raster_buffer->UnlockForWrite();
+}
+
+void ResourceProvider::AcquirePixelBuffer(Resource* resource) {
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
+ "ResourceProvider::AcquirePixelBuffer");
+
+ DCHECK(resource->origin == Resource::Internal);
+ DCHECK_EQ(resource->exported_count, 0);
+ DCHECK(!resource->image_id);
+ DCHECK_NE(ETC1, resource->format);
+
+ DCHECK_EQ(GLTexture, resource->type);
+ GLES2Interface* gl = ContextGL();
+ DCHECK(gl);
+ if (!resource->gl_pixel_buffer_id)
+ resource->gl_pixel_buffer_id = buffer_id_allocator_->NextId();
+ gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
+ resource->gl_pixel_buffer_id);
+ unsigned bytes_per_pixel = BitsPerPixel(resource->format) / 8;
+ gl->BufferData(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
+ resource->size.height() *
+ RoundUp(bytes_per_pixel * resource->size.width(), 4u),
+ NULL,
+ GL_DYNAMIC_DRAW);
+ gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
+}
+
+void ResourceProvider::ReleasePixelBuffer(Resource* resource) {
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
+ "ResourceProvider::ReleasePixelBuffer");
+
+ DCHECK(resource->origin == Resource::Internal);
DCHECK_EQ(resource->exported_count, 0);
DCHECK(!resource->image_id);
@@ -1411,70 +1852,61 @@ void ResourceProvider::ReleasePixelBuffer(ResourceId id) {
if (resource->pending_set_pixels) {
DCHECK(resource->set_pixels_completion_forced);
resource->pending_set_pixels = false;
- UnlockForWrite(id);
- }
-
- if (resource->type == GLTexture) {
- if (!resource->gl_pixel_buffer_id)
- return;
- GLES2Interface* gl = ContextGL();
- DCHECK(gl);
- gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
- resource->gl_pixel_buffer_id);
- gl->BufferData(
- GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0, NULL, GL_DYNAMIC_DRAW);
- gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
+ resource->locked_for_write = false;
}
- if (resource->pixels) {
- if (!resource->pixel_buffer)
- return;
- delete[] resource->pixel_buffer;
- resource->pixel_buffer = NULL;
- }
+ DCHECK_EQ(GLTexture, resource->type);
+ if (!resource->gl_pixel_buffer_id)
+ return;
+ GLES2Interface* gl = ContextGL();
+ DCHECK(gl);
+ gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
+ resource->gl_pixel_buffer_id);
+ gl->BufferData(
+ GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0, NULL, GL_DYNAMIC_DRAW);
+ gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
}
-uint8_t* ResourceProvider::MapPixelBuffer(ResourceId id) {
- Resource* resource = GetResource(id);
- DCHECK(!resource->external);
+uint8_t* ResourceProvider::MapPixelBuffer(const Resource* resource,
+ int* stride) {
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
+ "ResourceProvider::MapPixelBuffer");
+
+ DCHECK(resource->origin == Resource::Internal);
DCHECK_EQ(resource->exported_count, 0);
DCHECK(!resource->image_id);
- if (resource->type == GLTexture) {
- GLES2Interface* gl = ContextGL();
- DCHECK(gl);
- DCHECK(resource->gl_pixel_buffer_id);
- gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
- resource->gl_pixel_buffer_id);
- uint8_t* image = static_cast<uint8_t*>(gl->MapBufferCHROMIUM(
- GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, GL_WRITE_ONLY));
- gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
- // Buffer is required to be 4-byte aligned.
- CHECK(!(reinterpret_cast<intptr_t>(image) & 3));
- return image;
- }
-
- if (resource->pixels)
- return resource->pixel_buffer;
-
- return NULL;
-}
-
-void ResourceProvider::UnmapPixelBuffer(ResourceId id) {
- Resource* resource = GetResource(id);
- DCHECK(!resource->external);
+ *stride = 0;
+ DCHECK_EQ(GLTexture, resource->type);
+ GLES2Interface* gl = ContextGL();
+ DCHECK(gl);
+ DCHECK(resource->gl_pixel_buffer_id);
+ gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
+ resource->gl_pixel_buffer_id);
+ uint8_t* image = static_cast<uint8_t*>(gl->MapBufferCHROMIUM(
+ GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, GL_WRITE_ONLY));
+ gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
+ // Buffer is required to be 4-byte aligned.
+ CHECK(!(reinterpret_cast<intptr_t>(image) & 3));
+ return image;
+}
+
+void ResourceProvider::UnmapPixelBuffer(const Resource* resource) {
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
+ "ResourceProvider::UnmapPixelBuffer");
+
+ DCHECK(resource->origin == Resource::Internal);
DCHECK_EQ(resource->exported_count, 0);
DCHECK(!resource->image_id);
- if (resource->type == GLTexture) {
- GLES2Interface* gl = ContextGL();
- DCHECK(gl);
- DCHECK(resource->gl_pixel_buffer_id);
- gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
- resource->gl_pixel_buffer_id);
- gl->UnmapBufferCHROMIUM(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM);
- gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
- }
+ DCHECK_EQ(GLTexture, resource->type);
+ GLES2Interface* gl = ContextGL();
+ DCHECK(gl);
+ DCHECK(resource->gl_pixel_buffer_id);
+ gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
+ resource->gl_pixel_buffer_id);
+ gl->UnmapBufferCHROMIUM(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM);
+ gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
}
GLenum ResourceProvider::BindForSampling(
@@ -1498,23 +1930,21 @@ GLenum ResourceProvider::BindForSampling(
resource->filter = filter;
}
- if (resource->image_id && resource->dirty_image) {
- // Release image currently bound to texture.
- if (resource->bound_image_id)
- gl->ReleaseTexImage2DCHROMIUM(target, resource->bound_image_id);
- gl->BindTexImage2DCHROMIUM(target, resource->image_id);
- resource->bound_image_id = resource->image_id;
- resource->dirty_image = false;
- }
+ if (resource->image_id && resource->dirty_image)
+ BindImageForSampling(resource);
return target;
}
void ResourceProvider::BeginSetPixels(ResourceId id) {
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
+ "ResourceProvider::BeginSetPixels");
+
Resource* resource = GetResource(id);
DCHECK(!resource->pending_set_pixels);
LazyCreate(resource);
+ DCHECK(resource->origin == Resource::Internal);
DCHECK(resource->gl_id || resource->allocated);
DCHECK(ReadLockFenceHasPassed(resource));
DCHECK(!resource->image_id);
@@ -1523,58 +1953,51 @@ void ResourceProvider::BeginSetPixels(ResourceId id) {
resource->allocated = true;
LockForWrite(id);
- if (resource->gl_id) {
- GLES2Interface* gl = ContextGL();
- DCHECK(gl);
- DCHECK(resource->gl_pixel_buffer_id);
- DCHECK_EQ(resource->target, static_cast<GLenum>(GL_TEXTURE_2D));
- gl->BindTexture(GL_TEXTURE_2D, resource->gl_id);
- gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
- resource->gl_pixel_buffer_id);
- if (!resource->gl_upload_query_id)
- gl->GenQueriesEXT(1, &resource->gl_upload_query_id);
- gl->BeginQueryEXT(GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM,
- resource->gl_upload_query_id);
- if (allocate) {
- gl->AsyncTexImage2DCHROMIUM(GL_TEXTURE_2D,
- 0, /* level */
- GLInternalFormat(resource->format),
- resource->size.width(),
- resource->size.height(),
- 0, /* border */
- GLDataFormat(resource->format),
- GLDataType(resource->format),
- NULL);
- } else {
- gl->AsyncTexSubImage2DCHROMIUM(GL_TEXTURE_2D,
- 0, /* level */
- 0, /* x */
- 0, /* y */
- resource->size.width(),
- resource->size.height(),
- GLDataFormat(resource->format),
- GLDataType(resource->format),
- NULL);
- }
- gl->EndQueryEXT(GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM);
- gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
- }
-
- if (resource->pixels) {
- DCHECK(!resource->mailbox.IsValid());
- DCHECK(resource->pixel_buffer);
- DCHECK_EQ(RGBA_8888, resource->format);
-
- std::swap(resource->pixels, resource->pixel_buffer);
- delete[] resource->pixel_buffer;
- resource->pixel_buffer = NULL;
+ DCHECK_EQ(GLTexture, resource->type);
+ DCHECK(resource->gl_id);
+ GLES2Interface* gl = ContextGL();
+ DCHECK(gl);
+ DCHECK(resource->gl_pixel_buffer_id);
+ DCHECK_EQ(resource->target, static_cast<GLenum>(GL_TEXTURE_2D));
+ gl->BindTexture(GL_TEXTURE_2D, resource->gl_id);
+ gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
+ resource->gl_pixel_buffer_id);
+ if (!resource->gl_upload_query_id)
+ gl->GenQueriesEXT(1, &resource->gl_upload_query_id);
+ gl->BeginQueryEXT(GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM,
+ resource->gl_upload_query_id);
+ if (allocate) {
+ gl->AsyncTexImage2DCHROMIUM(GL_TEXTURE_2D,
+ 0, /* level */
+ GLInternalFormat(resource->format),
+ resource->size.width(),
+ resource->size.height(),
+ 0, /* border */
+ GLDataFormat(resource->format),
+ GLDataType(resource->format),
+ NULL);
+ } else {
+ gl->AsyncTexSubImage2DCHROMIUM(GL_TEXTURE_2D,
+ 0, /* level */
+ 0, /* x */
+ 0, /* y */
+ resource->size.width(),
+ resource->size.height(),
+ GLDataFormat(resource->format),
+ GLDataType(resource->format),
+ NULL);
}
+ gl->EndQueryEXT(GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM);
+ gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
resource->pending_set_pixels = true;
resource->set_pixels_completion_forced = false;
}
void ResourceProvider::ForceSetPixelsToComplete(ResourceId id) {
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
+ "ResourceProvider::ForceSetPixelsToComplete");
+
Resource* resource = GetResource(id);
DCHECK(resource->locked_for_write);
DCHECK(resource->pending_set_pixels);
@@ -1591,6 +2014,9 @@ void ResourceProvider::ForceSetPixelsToComplete(ResourceId id) {
}
bool ResourceProvider::DidSetPixelsComplete(ResourceId id) {
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
+ "ResourceProvider::DidSetPixelsComplete");
+
Resource* resource = GetResource(id);
DCHECK(resource->locked_for_write);
DCHECK(resource->pending_set_pixels);
@@ -1622,13 +2048,15 @@ GLenum ResourceProvider::TargetForTesting(ResourceId id) {
}
void ResourceProvider::LazyCreate(Resource* resource) {
- if (resource->type != GLTexture || resource->gl_id != 0)
+ if (resource->type != GLTexture || resource->origin != Resource::Internal)
return;
- // Early out for resources that don't require texture creation.
- if (resource->texture_pool == 0)
+ if (resource->gl_id)
return;
+ DCHECK(resource->texture_pool);
+ DCHECK(resource->origin == Resource::Internal);
+ DCHECK(!resource->mailbox.IsValid());
resource->gl_id = texture_id_allocator_->NextId();
GLES2Interface* gl = ContextGL();
@@ -1697,15 +2125,27 @@ void ResourceProvider::LazyAllocate(Resource* resource) {
}
}
+void ResourceProvider::BindImageForSampling(Resource* resource) {
+ GLES2Interface* gl = ContextGL();
+ DCHECK(resource->gl_id);
+ DCHECK(resource->image_id);
+
+ // Release image currently bound to texture.
+ if (resource->bound_image_id)
+ gl->ReleaseTexImage2DCHROMIUM(resource->target, resource->bound_image_id);
+ gl->BindTexImage2DCHROMIUM(resource->target, resource->image_id);
+ resource->bound_image_id = resource->image_id;
+ resource->dirty_image = false;
+}
+
void ResourceProvider::EnableReadLockFences(ResourceProvider::ResourceId id,
bool enable) {
Resource* resource = GetResource(id);
resource->enable_read_lock_fences = enable;
}
-void ResourceProvider::AcquireImage(ResourceId id) {
- Resource* resource = GetResource(id);
- DCHECK(!resource->external);
+void ResourceProvider::AcquireImage(Resource* resource) {
+ DCHECK(resource->origin == Resource::Internal);
DCHECK_EQ(resource->exported_count, 0);
if (resource->type != GLTexture)
@@ -1720,13 +2160,13 @@ void ResourceProvider::AcquireImage(ResourceId id) {
resource->image_id =
gl->CreateImageCHROMIUM(resource->size.width(),
resource->size.height(),
- TextureToStorageFormat(resource->format));
+ TextureToStorageFormat(resource->format),
+ GL_IMAGE_MAP_CHROMIUM);
DCHECK(resource->image_id);
}
-void ResourceProvider::ReleaseImage(ResourceId id) {
- Resource* resource = GetResource(id);
- DCHECK(!resource->external);
+void ResourceProvider::ReleaseImage(Resource* resource) {
+ DCHECK(resource->origin == Resource::Internal);
DCHECK_EQ(resource->exported_count, 0);
if (!resource->image_id)
@@ -1741,63 +2181,92 @@ 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->external);
+ DCHECK(resource->origin == Resource::Internal);
DCHECK_EQ(resource->exported_count, 0);
- if (resource->image_id) {
+ if (resource->type == GLTexture) {
+ DCHECK(resource->image_id);
GLES2Interface* gl = ContextGL();
DCHECK(gl);
- return static_cast<uint8_t*>(
- gl->MapImageCHROMIUM(resource->image_id, GL_READ_WRITE));
+ // MapImageCHROMIUM should be called prior to GetImageParameterivCHROMIUM.
+ uint8_t* pixels =
+ static_cast<uint8_t*>(gl->MapImageCHROMIUM(resource->image_id));
+ gl->GetImageParameterivCHROMIUM(
+ resource->image_id, GL_IMAGE_ROWBYTES_CHROMIUM, stride);
+ return pixels;
}
-
- if (resource->pixels)
- return resource->pixels;
-
- return NULL;
+ DCHECK_EQ(Bitmap, resource->type);
+ *stride = 0;
+ return resource->pixels;
}
-void ResourceProvider::UnmapImage(ResourceId id) {
- Resource* resource = GetResource(id);
- DCHECK(!resource->external);
+void ResourceProvider::UnmapImage(const Resource* resource) {
+ DCHECK(resource->origin == Resource::Internal);
DCHECK_EQ(resource->exported_count, 0);
if (resource->image_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->external);
- DCHECK_EQ(resource->exported_count, 0);
+void ResourceProvider::CopyResource(ResourceId source_id, ResourceId dest_id) {
+ TRACE_EVENT0("cc", "ResourceProvider::CopyResource");
- int stride = 0;
+ Resource* source_resource = GetResource(source_id);
+ DCHECK(!source_resource->lock_for_read_count);
+ DCHECK(source_resource->origin == Resource::Internal);
+ DCHECK_EQ(source_resource->exported_count, 0);
+ DCHECK(source_resource->allocated);
+ LazyCreate(source_resource);
- if (resource->image_id) {
- GLES2Interface* gl = ContextGL();
- DCHECK(gl);
- gl->GetImageParameterivCHROMIUM(
- resource->image_id, GL_IMAGE_ROWBYTES_CHROMIUM, &stride);
- }
+ Resource* dest_resource = GetResource(dest_id);
+ DCHECK(!dest_resource->locked_for_write);
+ DCHECK(!dest_resource->lock_for_read_count);
+ DCHECK(dest_resource->origin == Resource::Internal);
+ DCHECK_EQ(dest_resource->exported_count, 0);
+ LazyCreate(dest_resource);
- return stride;
-}
+ DCHECK_EQ(source_resource->type, dest_resource->type);
+ DCHECK_EQ(source_resource->format, dest_resource->format);
+ DCHECK(source_resource->size == dest_resource->size);
-base::SharedMemory* ResourceProvider::GetSharedMemory(ResourceId id) {
- Resource* resource = GetResource(id);
- DCHECK(!resource->external);
- DCHECK_EQ(resource->exported_count, 0);
+ if (source_resource->type == GLTexture) {
+ GLES2Interface* gl = ContextGL();
+ DCHECK(gl);
+ if (source_resource->image_id && source_resource->dirty_image) {
+ gl->BindTexture(source_resource->target, source_resource->gl_id);
+ BindImageForSampling(source_resource);
+ }
+ DCHECK(use_sync_query_) << "CHROMIUM_sync_query extension missing";
+ if (!source_resource->gl_read_lock_query_id)
+ gl->GenQueriesEXT(1, &source_resource->gl_read_lock_query_id);
+ gl->BeginQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM,
+ source_resource->gl_read_lock_query_id);
+ DCHECK(!dest_resource->image_id);
+ dest_resource->allocated = true;
+ gl->CopyTextureCHROMIUM(dest_resource->target,
+ source_resource->gl_id,
+ dest_resource->gl_id,
+ 0,
+ GLInternalFormat(dest_resource->format),
+ GLDataType(dest_resource->format));
+ // End query and create a read lock fence that will prevent access to
+ // source resource until CopyTextureCHROMIUM command has completed.
+ gl->EndQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM);
+ source_resource->read_lock_fence = make_scoped_refptr(
+ new QueryFence(gl, source_resource->gl_read_lock_query_id));
+ } else {
+ DCHECK_EQ(Bitmap, source_resource->type);
+ DCHECK_EQ(RGBA_8888, source_resource->format);
+ LazyAllocate(dest_resource);
- if (!resource->shared_bitmap)
- return NULL;
- return resource->shared_bitmap->memory();
+ size_t bytes = SharedBitmap::CheckedSizeInBytes(source_resource->size);
+ memcpy(dest_resource->pixels, source_resource->pixels, bytes);
+ }
}
GLint ResourceProvider::GetActiveTextureUnit(GLES2Interface* gl) {
@@ -1811,4 +2280,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