#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"
return storage_format;
}
-bool IsFormatSupportedForStorage(ResourceFormat format) {
+bool IsFormatSupportedForStorage(ResourceFormat format, bool use_bgra) {
switch (format) {
case RGBA_8888:
- case BGRA_8888:
return true;
+ case BGRA_8888:
+ return use_bgra;
case RGBA_4444:
case ALPHA_8:
case LUMINANCE_8:
return kSkia8888_GrPixelConfig;
}
-void CopyBitmap(const SkBitmap& src, uint8_t* dst, SkColorType dst_color_type) {
- SkImageInfo dst_info = src.info();
- dst_info.fColorType = dst_color_type;
- // TODO(kaanb): The GL pipeline assumes a 4-byte alignment for the
- // bitmap data. There will be no need to call SkAlign4 once crbug.com/293728
- // is fixed.
- const size_t dst_row_bytes = SkAlign4(dst_info.minRowBytes());
- CHECK_EQ(0u, dst_row_bytes % 4);
- bool success = src.readPixels(dst_info, dst, dst_row_bytes, 0, 0);
- CHECK_EQ(true, success);
-}
-
class ScopedSetActiveTexture {
public:
ScopedSetActiveTexture(GLES2Interface* gl, GLenum unit)
bound_image_id(0),
texture_pool(0),
wrap_mode(0),
- hint(TextureUsageAny),
+ hint(TextureHintImmutable),
type(InvalidType),
format(RGBA_8888),
shared_bitmap(NULL) {
GLenum filter,
GLenum texture_pool,
GLint wrap_mode,
- TextureUsageHint hint,
+ TextureHint hint,
ResourceFormat format)
: child_id(0),
gl_id(texture_id),
bound_image_id(0),
texture_pool(0),
wrap_mode(wrap_mode),
- hint(TextureUsageAny),
+ hint(TextureHintImmutable),
type(Bitmap),
format(RGBA_8888),
shared_bitmap(bitmap) {
bound_image_id(0),
texture_pool(0),
wrap_mode(wrap_mode),
- hint(TextureUsageAny),
+ hint(TextureHintImmutable),
type(Bitmap),
format(RGBA_8888),
shared_bitmap_id(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() {
- 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::GpuRasterBuffer::GpuRasterBuffer(
- 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::GpuRasterBuffer::~GpuRasterBuffer() {
-}
-
-SkCanvas* ResourceProvider::GpuRasterBuffer::DoLockForWrite() {
- if (!surface_)
- surface_ = CreateSurface();
- surface_generation_id_ = surface_ ? surface_->generationID() : 0u;
- return surface_ ? surface_->getCanvas() : NULL;
-}
-
-bool ResourceProvider::GpuRasterBuffer::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::GpuRasterBuffer::CreateSurface() {
- DCHECK_EQ(GLTexture, resource()->type);
- DCHECK(resource()->gl_id);
-
- class GrContext* gr_context = resource_provider()->GrContext();
- // TODO(alokp): Implement TestContextProvider::GrContext().
- if (!gr_context)
- return skia::RefPtr<SkSurface>();
-
- 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;
- return skia::AdoptRef(SkSurface::NewRenderTargetDirect(
- gr_texture->asRenderTarget(), text_render_mode));
-}
-
-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 ALPHA_8:
- 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) {}
ResourceProvider::Child::~Child() {}
scoped_ptr<ResourceProvider> ResourceProvider::Create(
OutputSurface* output_surface,
SharedBitmapManager* shared_bitmap_manager,
+ BlockingTaskRunner* blocking_main_thread_task_runner,
int highp_threshold_min,
bool use_rgba_4444_texture_format,
size_t id_allocation_chunk_size,
scoped_ptr<ResourceProvider> resource_provider(
new ResourceProvider(output_surface,
shared_bitmap_manager,
+ blocking_main_thread_task_runner,
highp_threshold_min,
use_rgba_4444_texture_format,
id_allocation_chunk_size,
ResourceProvider::ResourceId ResourceProvider::CreateResource(
const gfx::Size& size,
GLint wrap_mode,
- TextureUsageHint hint,
+ TextureHint hint,
ResourceFormat format) {
DCHECK(!size.IsEmpty());
switch (default_resource_type_) {
const gfx::Size& size,
GLenum target,
GLint wrap_mode,
- TextureUsageHint hint,
+ TextureHint hint,
ResourceFormat format) {
DCHECK(!size.IsEmpty());
switch (default_resource_type_) {
GLenum target,
GLenum texture_pool,
GLint wrap_mode,
- TextureUsageHint hint,
+ TextureHint hint,
ResourceFormat format) {
DCHECK_LE(size.width(), max_texture_size_);
DCHECK_LE(size.height(), max_texture_size_);
GL_LINEAR,
GL_TEXTURE_POOL_UNMANAGED_CHROMIUM,
GL_CLAMP_TO_EDGE,
- TextureUsageAny,
+ TextureHintImmutable,
RGBA_8888);
LazyCreate(&resource);
GLES2Interface* gl = ContextGL();
ResourceProvider::ResourceId ResourceProvider::CreateResourceFromTextureMailbox(
const TextureMailbox& mailbox,
- scoped_ptr<SingleReleaseCallback> release_callback) {
+ scoped_ptr<SingleReleaseCallbackImpl> release_callback_impl) {
DCHECK(thread_checker_.CalledOnValidThread());
// Just store the information. Mailbox will be consumed in LockForRead().
ResourceId id = next_id_++;
GL_LINEAR,
0,
GL_CLAMP_TO_EDGE,
- TextureUsageAny,
+ TextureHintImmutable,
RGBA_8888);
} else {
DCHECK(mailbox.IsSharedMemory());
}
resource.allocated = true;
resource.mailbox = mailbox;
- resource.release_callback =
- base::Bind(&SingleReleaseCallback::Run,
- base::Owned(release_callback.release()));
+ resource.release_callback_impl =
+ base::Bind(&SingleReleaseCallbackImpl::Run,
+ base::Owned(release_callback_impl.release()));
resource.allow_overlay = mailbox.allow_overlay();
return id;
}
if (style == ForShutdown && resource->exported_count > 0)
lost_resource = true;
- resource->gpu_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();
resource->shared_bitmap = NULL;
}
}
- resource->release_callback.Run(sync_point, lost_resource);
+ resource->release_callback_impl.Run(
+ sync_point, lost_resource, blocking_main_thread_task_runner_);
}
if (resource->gl_id) {
GLES2Interface* gl = ContextGL();
if (resource->type == GLTexture && !resource->gl_id) {
DCHECK(resource->origin != Resource::Internal);
DCHECK(resource->mailbox.IsTexture());
+
+ // Mailbox sync_points must be processed by a call to
+ // WaitSyncPointIfNeeded() prior to calling LockForRead().
+ DCHECK(!resource->mailbox.sync_point());
+
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,
resource->lock_for_read_count++;
if (resource->read_lock_fences_enabled) {
- if (current_read_lock_fence_)
+ if (current_read_lock_fence_.get())
current_read_lock_fence_->Set();
resource->read_lock_fence = current_read_lock_fence_;
}
resource_provider_->UnlockForWrite(resource_id_);
}
-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,
- bool use_distance_field_text)
+ResourceProvider::ResourceProvider(
+ OutputSurface* output_surface,
+ SharedBitmapManager* shared_bitmap_manager,
+ BlockingTaskRunner* blocking_main_thread_task_runner,
+ int highp_threshold_min,
+ bool use_rgba_4444_texture_format,
+ size_t id_allocation_chunk_size,
+ bool use_distance_field_text)
: output_surface_(output_surface),
shared_bitmap_manager_(shared_bitmap_manager),
+ blocking_main_thread_task_runner_(blocking_main_thread_task_runner),
lost_output_surface_(false),
highp_threshold_min_(highp_threshold_min),
next_id_(1),
next_child_(1),
default_resource_type_(InvalidType),
use_texture_storage_ext_(false),
+ use_texture_format_bgra_(false),
use_texture_usage_hint_(false),
use_compressed_texture_etc1_(false),
max_texture_size_(0),
bool use_bgra = caps.gpu.texture_format_bgra8888;
use_texture_storage_ext_ = caps.gpu.texture_storage;
+ use_texture_format_bgra_ = caps.gpu.texture_format_bgra8888;
use_texture_usage_hint_ = caps.gpu.texture_usage;
use_compressed_texture_etc1_ = caps.gpu.texture_format_etc1;
use_sync_query_ = caps.gpu.sync_query;
TRACE_EVENT0("cc", "ResourceProvider::ReceiveFromChild dropping invalid");
ReturnedResourceArray to_return;
to_return.push_back(it->ToReturnedResource());
- child_info.return_callback.Run(to_return);
+ child_info.return_callback.Run(to_return,
+ blocking_main_thread_task_runner_);
continue;
}
it->filter,
0,
it->is_repeated ? GL_REPEAT : GL_CLAMP_TO_EDGE,
- TextureUsageAny,
+ TextureHintImmutable,
it->format);
resource.mailbox = TextureMailbox(it->mailbox_holder.mailbox,
it->mailbox_holder.texture_target,
// Need to wait for the current read lock fence to pass before we can
// recycle this resource.
if (resource->read_lock_fences_enabled) {
- if (current_read_lock_fence_)
+ if (current_read_lock_fence_.get())
current_read_lock_fence_->Set();
resource->read_lock_fence = current_read_lock_fence_;
}
}
if (!to_return.empty())
- child_info->return_callback.Run(to_return);
+ child_info->return_callback.Run(to_return,
+ blocking_main_thread_task_runner_);
if (child_info->marked_for_deletion &&
child_info->parent_to_child_map.empty()) {
}
}
-SkCanvas* ResourceProvider::MapGpuRasterBuffer(ResourceId id) {
- // Resource needs to be locked for write since GpuRasterBuffer writes
- // directly to it.
- LockForWrite(id);
- Resource* resource = GetResource(id);
- if (!resource->gpu_raster_buffer.get()) {
- resource->gpu_raster_buffer.reset(
- new GpuRasterBuffer(resource, this, use_distance_field_text_));
- }
- return resource->gpu_raster_buffer->LockForWrite();
-}
-
-void ResourceProvider::UnmapGpuRasterBuffer(ResourceId id) {
- Resource* resource = GetResource(id);
- DCHECK(resource->gpu_raster_buffer.get());
- resource->gpu_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();
-}
-
-bool ResourceProvider::UnmapImageRasterBuffer(ResourceId id) {
- Resource* resource = GetResource(id);
- resource->dirty_image = true;
- return resource->image_raster_buffer->UnlockForWrite();
-}
-
-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();
-}
-
-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) {
+void ResourceProvider::AcquirePixelBuffer(ResourceId id) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
"ResourceProvider::AcquirePixelBuffer");
+ Resource* resource = GetResource(id);
DCHECK(resource->origin == Resource::Internal);
DCHECK_EQ(resource->exported_count, 0);
DCHECK(!resource->image_id);
gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
}
-void ResourceProvider::ReleasePixelBuffer(Resource* resource) {
+void ResourceProvider::ReleasePixelBuffer(ResourceId id) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
"ResourceProvider::ReleasePixelBuffer");
+ Resource* resource = GetResource(id);
DCHECK(resource->origin == Resource::Internal);
DCHECK_EQ(resource->exported_count, 0);
DCHECK(!resource->image_id);
gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
}
-uint8_t* ResourceProvider::MapPixelBuffer(const Resource* resource,
- int* stride) {
+uint8_t* ResourceProvider::MapPixelBuffer(ResourceId id, int* stride) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
"ResourceProvider::MapPixelBuffer");
+ Resource* resource = GetResource(id);
DCHECK(resource->origin == Resource::Internal);
DCHECK_EQ(resource->exported_count, 0);
DCHECK(!resource->image_id);
return image;
}
-void ResourceProvider::UnmapPixelBuffer(const Resource* resource) {
+void ResourceProvider::UnmapPixelBuffer(ResourceId id) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
"ResourceProvider::UnmapPixelBuffer");
+ Resource* resource = GetResource(id);
DCHECK(resource->origin == Resource::Internal);
DCHECK_EQ(resource->exported_count, 0);
DCHECK(!resource->image_id);
gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
}
-GLenum ResourceProvider::BindForSampling(
- ResourceProvider::ResourceId resource_id,
- GLenum unit,
- GLenum filter) {
+GLenum ResourceProvider::BindForSampling(ResourceId resource_id,
+ GLenum unit,
+ GLenum filter) {
DCHECK(thread_checker_.CalledOnValidThread());
GLES2Interface* gl = ContextGL();
ResourceMap::iterator it = resources_.find(resource_id);
"ResourceProvider::ForceSetPixelsToComplete");
Resource* resource = GetResource(id);
+
DCHECK(resource->locked_for_write);
DCHECK(resource->pending_set_pixels);
DCHECK(!resource->set_pixels_completion_forced);
"ResourceProvider::DidSetPixelsComplete");
Resource* resource = GetResource(id);
+
DCHECK(resource->locked_for_write);
DCHECK(resource->pending_set_pixels);
// Create and set texture properties. Allocation is delayed until needed.
GLC(gl, gl->BindTexture(resource->target, resource->gl_id));
GLC(gl,
- gl->TexParameteri(resource->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
+ gl->TexParameteri(
+ resource->target, GL_TEXTURE_MIN_FILTER, resource->original_filter));
GLC(gl,
- gl->TexParameteri(resource->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
+ gl->TexParameteri(
+ resource->target, GL_TEXTURE_MAG_FILTER, resource->original_filter));
GLC(gl,
gl->TexParameteri(
resource->target, GL_TEXTURE_WRAP_S, resource->wrap_mode));
GLC(gl,
gl->TexParameteri(
resource->target, GL_TEXTURE_POOL_CHROMIUM, resource->texture_pool));
- if (use_texture_usage_hint_ && resource->hint == TextureUsageFramebuffer) {
+ if (use_texture_usage_hint_ && (resource->hint & TextureHintFramebuffer)) {
GLC(gl,
gl->TexParameteri(resource->target,
GL_TEXTURE_USAGE_ANGLE,
void ResourceProvider::LazyAllocate(Resource* resource) {
DCHECK(resource);
+ if (resource->allocated)
+ return;
LazyCreate(resource);
-
- DCHECK(resource->gl_id || resource->allocated);
- if (resource->allocated || !resource->gl_id)
+ if (!resource->gl_id)
return;
resource->allocated = true;
GLES2Interface* gl = ContextGL();
DCHECK_EQ(resource->target, static_cast<GLenum>(GL_TEXTURE_2D));
ResourceFormat format = resource->format;
GLC(gl, gl->BindTexture(GL_TEXTURE_2D, resource->gl_id));
- if (use_texture_storage_ext_ && IsFormatSupportedForStorage(format) &&
- resource->hint != TextureUsageFramebuffer) {
+ if (use_texture_storage_ext_ &&
+ IsFormatSupportedForStorage(format, use_texture_format_bgra_) &&
+ (resource->hint & TextureHintImmutable)) {
GLenum storage_format = TextureToStorageFormat(format);
GLC(gl,
gl->TexStorage2DEXT(
resource->dirty_image = false;
}
-void ResourceProvider::EnableReadLockFences(ResourceProvider::ResourceId id) {
+void ResourceProvider::EnableReadLockFences(ResourceId id) {
Resource* resource = GetResource(id);
resource->read_lock_fences_enabled = true;
}
-void ResourceProvider::AcquireImage(Resource* resource) {
+void ResourceProvider::AcquireImage(ResourceId id) {
+ Resource* resource = GetResource(id);
DCHECK(resource->origin == Resource::Internal);
DCHECK_EQ(resource->exported_count, 0);
-
- if (resource->type != GLTexture)
- return;
+ DCHECK_EQ(GLTexture, resource->type);
if (resource->image_id)
return;
DCHECK(resource->image_id);
}
-void ResourceProvider::ReleaseImage(Resource* resource) {
+void ResourceProvider::ReleaseImage(ResourceId id) {
+ Resource* resource = GetResource(id);
DCHECK(resource->origin == Resource::Internal);
DCHECK_EQ(resource->exported_count, 0);
+ DCHECK_EQ(GLTexture, resource->type);
if (!resource->image_id)
return;
resource->allocated = false;
}
-uint8_t* ResourceProvider::MapImage(const Resource* resource, int* stride) {
+uint8_t* ResourceProvider::MapImage(ResourceId id, int* stride) {
+ Resource* resource = GetResource(id);
DCHECK(ReadLockFenceHasPassed(resource));
DCHECK(resource->origin == Resource::Internal);
DCHECK_EQ(resource->exported_count, 0);
+ DCHECK(resource->image_id);
- if (resource->type == GLTexture) {
- DCHECK(resource->image_id);
- GLES2Interface* gl = ContextGL();
- DCHECK(gl);
- // 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;
- }
- DCHECK_EQ(Bitmap, resource->type);
- *stride = 0;
- return resource->pixels;
+ LockForWrite(id);
+
+ GLES2Interface* gl = ContextGL();
+ DCHECK(gl);
+ // 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;
}
-void ResourceProvider::UnmapImage(const Resource* resource) {
+void ResourceProvider::UnmapImage(ResourceId id) {
+ Resource* resource = GetResource(id);
DCHECK(resource->origin == Resource::Internal);
DCHECK_EQ(resource->exported_count, 0);
+ DCHECK(resource->image_id);
+ DCHECK(resource->locked_for_write);
- if (resource->image_id) {
- GLES2Interface* gl = ContextGL();
- DCHECK(gl);
- gl->UnmapImageCHROMIUM(resource->image_id);
- }
+ GLES2Interface* gl = ContextGL();
+ DCHECK(gl);
+ gl->UnmapImageCHROMIUM(resource->image_id);
+ resource->dirty_image = true;
+
+ UnlockForWrite(id);
+}
+
+void ResourceProvider::AcquireSkSurface(ResourceId id) {
+ Resource* resource = GetResource(id);
+ DCHECK(resource->origin == Resource::Internal);
+ DCHECK_EQ(resource->exported_count, 0);
+ DCHECK_EQ(GLTexture, resource->type);
+
+ if (resource->sk_surface)
+ return;
+
+ class GrContext* gr_context = GrContext();
+ // TODO(alokp): Implement TestContextProvider::GrContext().
+ if (!gr_context)
+ return;
+
+ LazyAllocate(resource);
+
+ 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;
+ resource->sk_surface = skia::AdoptRef(SkSurface::NewRenderTargetDirect(
+ gr_texture->asRenderTarget(), text_render_mode));
+}
+
+void ResourceProvider::ReleaseSkSurface(ResourceId id) {
+ Resource* resource = GetResource(id);
+ DCHECK(resource->origin == Resource::Internal);
+ DCHECK_EQ(resource->exported_count, 0);
+ DCHECK_EQ(GLTexture, resource->type);
+
+ resource->sk_surface.clear();
+}
+
+SkSurface* ResourceProvider::LockForWriteToSkSurface(ResourceId id) {
+ Resource* resource = GetResource(id);
+ DCHECK(resource->origin == Resource::Internal);
+ DCHECK_EQ(resource->exported_count, 0);
+ DCHECK_EQ(GLTexture, resource->type);
+
+ LockForWrite(id);
+ return resource->sk_surface.get();
+}
+
+void ResourceProvider::UnlockForWriteToSkSurface(ResourceId id) {
+ UnlockForWrite(id);
}
void ResourceProvider::CopyResource(ResourceId source_id, ResourceId dest_id) {
DCHECK(!source_resource->lock_for_read_count);
DCHECK(source_resource->origin == Resource::Internal);
DCHECK_EQ(source_resource->exported_count, 0);
+ DCHECK_EQ(GLTexture, source_resource->type);
DCHECK(source_resource->allocated);
LazyCreate(source_resource);
DCHECK(!dest_resource->lock_for_read_count);
DCHECK(dest_resource->origin == Resource::Internal);
DCHECK_EQ(dest_resource->exported_count, 0);
+ DCHECK_EQ(GLTexture, dest_resource->type);
LazyCreate(dest_resource);
DCHECK_EQ(source_resource->type, dest_resource->type);
DCHECK_EQ(source_resource->format, dest_resource->format);
DCHECK(source_resource->size == dest_resource->size);
- 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);
-
- size_t bytes = SharedBitmap::CheckedSizeInBytes(source_resource->size);
- memcpy(dest_resource->pixels, source_resource->pixels, bytes);
+ 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));
+}
+
+void ResourceProvider::WaitSyncPointIfNeeded(ResourceId id) {
+ Resource* resource = GetResource(id);
+ DCHECK_EQ(resource->exported_count, 0);
+ DCHECK(resource->allocated);
+ if (resource->type != GLTexture || resource->gl_id)
+ return;
+ if (!resource->mailbox.sync_point())
+ return;
+ DCHECK(resource->mailbox.IsValid());
+ GLES2Interface* gl = ContextGL();
+ DCHECK(gl);
+ GLC(gl, gl->WaitSyncPointCHROMIUM(resource->mailbox.sync_point()));
+ resource->mailbox.set_sync_point(0);
}
GLint ResourceProvider::GetActiveTextureUnit(GLES2Interface* gl) {