summaryrefslogtreecommitdiff
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.cc866
1 files changed, 399 insertions, 467 deletions
diff --git a/chromium/cc/resources/resource_provider.cc b/chromium/cc/resources/resource_provider.cc
index 023a1cdbf06..eb774fe10b3 100644
--- a/chromium/cc/resources/resource_provider.cc
+++ b/chromium/cc/resources/resource_provider.cc
@@ -8,12 +8,12 @@
#include <limits>
#include "base/containers/hash_tables.h"
-#include "base/debug/trace_event.h"
+#include "base/metrics/histogram.h"
#include "base/stl_util.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
+#include "base/trace_event/trace_event.h"
#include "cc/base/util.h"
-#include "cc/output/gl_renderer.h" // For the GLC() macro.
#include "cc/resources/platform_color.h"
#include "cc/resources/returned_resource.h"
#include "cc/resources/shared_bitmap_manager.h"
@@ -26,6 +26,7 @@
#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/GrTextureProvider.h"
#include "ui/gfx/frame_time.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/vector2d.h"
@@ -75,6 +76,7 @@ GLenum TextureToStorageFormat(ResourceFormat format) {
case LUMINANCE_8:
case RGB_565:
case ETC1:
+ case RED_8:
NOTREACHED();
break;
}
@@ -93,6 +95,7 @@ bool IsFormatSupportedForStorage(ResourceFormat format, bool use_bgra) {
case LUMINANCE_8:
case RGB_565:
case ETC1:
+ case RED_8:
return false;
}
return false;
@@ -124,6 +127,7 @@ gfx::GpuMemoryBuffer::Format ToGpuMemoryBufferFormat(ResourceFormat format) {
case LUMINANCE_8:
case RGB_565:
case ETC1:
+ case RED_8:
break;
}
NOTREACHED();
@@ -137,13 +141,13 @@ class ScopedSetActiveTexture {
DCHECK_EQ(GL_TEXTURE0, ResourceProvider::GetActiveTextureUnit(gl_));
if (unit_ != GL_TEXTURE0)
- GLC(gl_, gl_->ActiveTexture(unit_));
+ gl_->ActiveTexture(unit_);
}
~ScopedSetActiveTexture() {
// Active unit being GL_TEXTURE0 is effectively the ground state.
if (unit_ != GL_TEXTURE0)
- GLC(gl_, gl_->ActiveTexture(GL_TEXTURE0));
+ gl_->ActiveTexture(GL_TEXTURE0);
}
private:
@@ -198,11 +202,11 @@ 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 {
+// Query object based fence implementation used to detect completion of copy
+// texture operations. Fence has passed when query result is available.
+class CopyTextureFence : public ResourceProvider::Fence {
public:
- QueryFence(gpu::gles2::GLES2Interface* gl, unsigned query_id)
+ CopyTextureFence(gpu::gles2::GLES2Interface* gl, unsigned query_id)
: gl_(gl), query_id_(query_id) {}
// Overridden from ResourceProvider::Fence:
@@ -211,61 +215,35 @@ class QueryFence : public ResourceProvider::Fence {
unsigned available = 1;
gl_->GetQueryObjectuivEXT(
query_id_, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
- return !!available;
+ if (!available)
+ return false;
+
+ ProcessResult();
+ return true;
}
void Wait() override {
- unsigned result = 0;
- gl_->GetQueryObjectuivEXT(query_id_, GL_QUERY_RESULT_EXT, &result);
+ // ProcessResult() will wait for result to become available.
+ ProcessResult();
}
private:
- ~QueryFence() override {}
+ ~CopyTextureFence() override {}
+
+ void ProcessResult() {
+ unsigned time_elapsed_us = 0;
+ gl_->GetQueryObjectuivEXT(query_id_, GL_QUERY_RESULT_EXT, &time_elapsed_us);
+ UMA_HISTOGRAM_CUSTOM_COUNTS("Renderer4.CopyTextureLatency", time_elapsed_us,
+ 0, 256000, 50);
+ }
gpu::gles2::GLES2Interface* gl_;
unsigned query_id_;
- DISALLOW_COPY_AND_ASSIGN(QueryFence);
+ DISALLOW_COPY_AND_ASSIGN(CopyTextureFence);
};
} // namespace
-ResourceProvider::Resource::Resource()
- : 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),
- read_lock_fences_enabled(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),
- texture_pool(0),
- wrap_mode(0),
- hint(TextureHintImmutable),
- type(InvalidType),
- format(RGBA_8888),
- shared_bitmap(NULL),
- gpu_memory_buffer(NULL) {
-}
-
ResourceProvider::Resource::~Resource() {}
ResourceProvider::Resource::Resource(GLuint texture_id,
@@ -307,12 +285,12 @@ ResourceProvider::Resource::Resource(GLuint texture_id,
texture_pool(texture_pool),
wrap_mode(wrap_mode),
hint(hint),
- type(GLTexture),
+ type(RESOURCE_TYPE_GL_TEXTURE),
format(format),
shared_bitmap(NULL),
gpu_memory_buffer(NULL) {
DCHECK(wrap_mode == GL_CLAMP_TO_EDGE || wrap_mode == GL_REPEAT);
- DCHECK_EQ(origin == Internal, !!texture_pool);
+ DCHECK_EQ(origin == INTERNAL, !!texture_pool);
}
ResourceProvider::Resource::Resource(uint8_t* pixels,
@@ -350,13 +328,13 @@ ResourceProvider::Resource::Resource(uint8_t* pixels,
bound_image_id(0),
texture_pool(0),
wrap_mode(wrap_mode),
- hint(TextureHintImmutable),
- type(Bitmap),
+ hint(TEXTURE_HINT_IMMUTABLE),
+ type(RESOURCE_TYPE_BITMAP),
format(RGBA_8888),
shared_bitmap(bitmap),
gpu_memory_buffer(NULL) {
DCHECK(wrap_mode == GL_CLAMP_TO_EDGE || wrap_mode == GL_REPEAT);
- DCHECK(origin == Delegated || pixels);
+ DCHECK(origin == DELEGATED || pixels);
if (bitmap)
shared_bitmap_id = bitmap->id();
}
@@ -395,8 +373,8 @@ ResourceProvider::Resource::Resource(const SharedBitmapId& bitmap_id,
bound_image_id(0),
texture_pool(0),
wrap_mode(wrap_mode),
- hint(TextureHintImmutable),
- type(Bitmap),
+ hint(TEXTURE_HINT_IMMUTABLE),
+ type(RESOURCE_TYPE_BITMAP),
format(RGBA_8888),
shared_bitmap_id(bitmap_id),
shared_bitmap(NULL),
@@ -404,7 +382,9 @@ ResourceProvider::Resource::Resource(const SharedBitmapId& bitmap_id,
DCHECK(wrap_mode == GL_CLAMP_TO_EDGE || wrap_mode == GL_REPEAT);
}
-ResourceProvider::Child::Child() : marked_for_deletion(false) {}
+ResourceProvider::Child::Child()
+ : marked_for_deletion(false), needs_sync_points(true) {
+}
ResourceProvider::Child::~Child() {}
@@ -416,31 +396,53 @@ scoped_ptr<ResourceProvider> ResourceProvider::Create(
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,
- gpu_memory_buffer_manager,
- blocking_main_thread_task_runner,
- highp_threshold_min,
- use_rgba_4444_texture_format,
- id_allocation_chunk_size));
-
- if (resource_provider->ContextGL())
+ ContextProvider* context_provider = output_surface->context_provider();
+ GLES2Interface* gl =
+ context_provider ? context_provider->ContextGL() : nullptr;
+ ResourceType default_resource_type =
+ gl ? RESOURCE_TYPE_GL_TEXTURE : RESOURCE_TYPE_BITMAP;
+
+ scoped_ptr<ResourceProvider> resource_provider(new ResourceProvider(
+ output_surface, shared_bitmap_manager, gpu_memory_buffer_manager,
+ blocking_main_thread_task_runner, highp_threshold_min,
+ default_resource_type, use_rgba_4444_texture_format,
+ id_allocation_chunk_size));
+
+ if (gl)
resource_provider->InitializeGL();
else
resource_provider->InitializeSoftware();
- DCHECK_NE(InvalidType, resource_provider->default_resource_type());
return resource_provider.Pass();
}
ResourceProvider::~ResourceProvider() {
while (!children_.empty())
- DestroyChildInternal(children_.begin(), ForShutdown);
+ DestroyChildInternal(children_.begin(), FOR_SHUTDOWN);
while (!resources_.empty())
- DeleteResourceInternal(resources_.begin(), ForShutdown);
+ DeleteResourceInternal(resources_.begin(), FOR_SHUTDOWN);
+
+ GLES2Interface* gl = ContextGL();
+ if (default_resource_type_ != RESOURCE_TYPE_GL_TEXTURE) {
+ // We are not in GL mode, but double check before returning.
+ DCHECK(!gl);
+ DCHECK(!texture_uploader_);
+ return;
+ }
+
+ 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(RESOURCE_TYPE_GL_TEXTURE, itr->second.type);
+ }
+#endif // DCHECK_IS_ON()
- CleanUpGLIfNeeded();
+ texture_uploader_ = nullptr;
+ texture_id_allocator_ = nullptr;
+ buffer_id_allocator_ = nullptr;
+ gl->Finish();
}
bool ResourceProvider::InUseByConsumer(ResourceId id) {
@@ -466,18 +468,16 @@ ResourceProvider::ResourceId ResourceProvider::CreateResource(
ResourceFormat format) {
DCHECK(!size.IsEmpty());
switch (default_resource_type_) {
- case GLTexture:
+ case RESOURCE_TYPE_GL_TEXTURE:
return CreateGLTexture(size,
GL_TEXTURE_2D,
GL_TEXTURE_POOL_UNMANAGED_CHROMIUM,
wrap_mode,
hint,
format);
- case Bitmap:
+ case RESOURCE_TYPE_BITMAP:
DCHECK_EQ(RGBA_8888, format);
return CreateBitmap(size, wrap_mode);
- case InvalidType:
- break;
}
LOG(FATAL) << "Invalid default resource type.";
@@ -492,18 +492,16 @@ ResourceProvider::ResourceId ResourceProvider::CreateManagedResource(
ResourceFormat format) {
DCHECK(!size.IsEmpty());
switch (default_resource_type_) {
- case GLTexture:
+ case RESOURCE_TYPE_GL_TEXTURE:
return CreateGLTexture(size,
target,
GL_TEXTURE_POOL_MANAGED_CHROMIUM,
wrap_mode,
hint,
format);
- case Bitmap:
+ case RESOURCE_TYPE_BITMAP:
DCHECK_EQ(RGBA_8888, format);
return CreateBitmap(size, wrap_mode);
- case InvalidType:
- break;
}
LOG(FATAL) << "Invalid default resource type.";
@@ -522,17 +520,10 @@ ResourceProvider::ResourceId ResourceProvider::CreateGLTexture(
DCHECK(thread_checker_.CalledOnValidThread());
ResourceId id = next_id_++;
- Resource resource(0,
- size,
- Resource::Internal,
- target,
- GL_LINEAR,
- texture_pool,
- wrap_mode,
- hint,
- format);
- resource.allocated = false;
- resources_[id] = resource;
+ Resource* resource = InsertResource(
+ id, Resource(0, size, Resource::INTERNAL, target, GL_LINEAR, texture_pool,
+ wrap_mode, hint, format));
+ resource->allocated = false;
return id;
}
@@ -540,24 +531,16 @@ ResourceProvider::ResourceId ResourceProvider::CreateBitmap(
const gfx::Size& size, GLint wrap_mode) {
DCHECK(thread_checker_.CalledOnValidThread());
- scoped_ptr<SharedBitmap> bitmap;
- if (shared_bitmap_manager_)
- bitmap = shared_bitmap_manager_->AllocateSharedBitmap(size);
-
- uint8_t* pixels;
- if (bitmap) {
- pixels = bitmap->pixels();
- } else {
- size_t bytes = SharedBitmap::CheckedSizeInBytes(size);
- pixels = new uint8_t[bytes];
- }
+ scoped_ptr<SharedBitmap> bitmap =
+ shared_bitmap_manager_->AllocateSharedBitmap(size);
+ uint8_t* pixels = bitmap->pixels();
DCHECK(pixels);
ResourceId id = next_id_++;
- Resource resource(
- pixels, bitmap.release(), size, Resource::Internal, GL_LINEAR, wrap_mode);
- resource.allocated = true;
- resources_[id] = resource;
+ Resource* resource =
+ InsertResource(id, Resource(pixels, bitmap.release(), size,
+ Resource::INTERNAL, GL_LINEAR, wrap_mode));
+ resource->allocated = true;
return id;
}
@@ -567,23 +550,17 @@ ResourceProvider::ResourceId ResourceProvider::CreateResourceFromIOSurface(
DCHECK(thread_checker_.CalledOnValidThread());
ResourceId id = next_id_++;
- Resource resource(0,
- gfx::Size(),
- Resource::Internal,
- GL_TEXTURE_RECTANGLE_ARB,
- GL_LINEAR,
- GL_TEXTURE_POOL_UNMANAGED_CHROMIUM,
- GL_CLAMP_TO_EDGE,
- TextureHintImmutable,
- RGBA_8888);
- LazyCreate(&resource);
+ Resource* resource = InsertResource(
+ id, Resource(0, gfx::Size(), Resource::INTERNAL, GL_TEXTURE_RECTANGLE_ARB,
+ GL_LINEAR, GL_TEXTURE_POOL_UNMANAGED_CHROMIUM,
+ GL_CLAMP_TO_EDGE, TEXTURE_HINT_IMMUTABLE, RGBA_8888));
+ LazyCreate(resource);
GLES2Interface* gl = ContextGL();
DCHECK(gl);
- gl->BindTexture(GL_TEXTURE_RECTANGLE_ARB, resource.gl_id);
+ 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;
+ resource->allocated = true;
return id;
}
@@ -594,41 +571,27 @@ ResourceProvider::ResourceId ResourceProvider::CreateResourceFromTextureMailbox(
// Just store the information. Mailbox will be consumed in LockForRead().
ResourceId id = next_id_++;
DCHECK(mailbox.IsValid());
- Resource& resource = resources_[id];
+ Resource* resource = nullptr;
if (mailbox.IsTexture()) {
- resource = Resource(0,
- gfx::Size(),
- Resource::External,
- mailbox.target(),
- GL_LINEAR,
- 0,
- GL_CLAMP_TO_EDGE,
- TextureHintImmutable,
- RGBA_8888);
+ resource = InsertResource(
+ id, Resource(0, gfx::Size(), Resource::EXTERNAL, mailbox.target(),
+ mailbox.nearest_neighbor() ? GL_NEAREST : GL_LINEAR, 0,
+ GL_CLAMP_TO_EDGE, TEXTURE_HINT_IMMUTABLE, RGBA_8888));
} else {
DCHECK(mailbox.IsSharedMemory());
- base::SharedMemory* shared_memory = mailbox.shared_memory();
- DCHECK(shared_memory->memory());
- uint8_t* pixels = reinterpret_cast<uint8_t*>(shared_memory->memory());
+ SharedBitmap* shared_bitmap = mailbox.shared_bitmap();
+ uint8_t* pixels = shared_bitmap->pixels();
DCHECK(pixels);
- scoped_ptr<SharedBitmap> shared_bitmap;
- if (shared_bitmap_manager_) {
- shared_bitmap =
- shared_bitmap_manager_->GetBitmapForSharedMemory(shared_memory);
- }
- resource = Resource(pixels,
- shared_bitmap.release(),
- mailbox.shared_memory_size(),
- Resource::External,
- GL_LINEAR,
- GL_CLAMP_TO_EDGE);
+ resource = InsertResource(
+ id, Resource(pixels, shared_bitmap, mailbox.shared_memory_size(),
+ Resource::EXTERNAL, GL_LINEAR, GL_CLAMP_TO_EDGE));
}
- resource.allocated = true;
- resource.mailbox = mailbox;
- resource.release_callback_impl =
+ resource->allocated = true;
+ resource->mailbox = mailbox;
+ resource->release_callback_impl =
base::Bind(&SingleReleaseCallbackImpl::Run,
base::Owned(release_callback_impl.release()));
- resource.allow_overlay = mailbox.allow_overlay();
+ resource->allow_overlay = mailbox.allow_overlay();
return id;
}
@@ -645,7 +608,7 @@ void ResourceProvider::DeleteResource(ResourceId id) {
resource->marked_for_deletion = true;
return;
} else {
- DeleteResourceInternal(it, Normal);
+ DeleteResourceInternal(it, NORMAL);
}
}
@@ -655,57 +618,52 @@ void ResourceProvider::DeleteResourceInternal(ResourceMap::iterator it,
Resource* resource = &it->second;
bool lost_resource = resource->lost;
- DCHECK(resource->exported_count == 0 || style != Normal);
- if (style == ForShutdown && resource->exported_count > 0)
+ DCHECK(resource->exported_count == 0 || style != NORMAL);
+ if (style == FOR_SHUTDOWN && resource->exported_count > 0)
lost_resource = true;
if (resource->image_id) {
- DCHECK(resource->origin == Resource::Internal);
+ DCHECK(resource->origin == Resource::INTERNAL);
GLES2Interface* gl = ContextGL();
DCHECK(gl);
- GLC(gl, gl->DestroyImageCHROMIUM(resource->image_id));
+ gl->DestroyImageCHROMIUM(resource->image_id);
}
if (resource->gl_upload_query_id) {
- DCHECK(resource->origin == Resource::Internal);
+ DCHECK(resource->origin == Resource::INTERNAL);
GLES2Interface* gl = ContextGL();
DCHECK(gl);
- GLC(gl, gl->DeleteQueriesEXT(1, &resource->gl_upload_query_id));
+ gl->DeleteQueriesEXT(1, &resource->gl_upload_query_id);
}
if (resource->gl_read_lock_query_id) {
- DCHECK(resource->origin == Resource::Internal);
+ DCHECK(resource->origin == Resource::INTERNAL);
GLES2Interface* gl = ContextGL();
DCHECK(gl);
- GLC(gl, gl->DeleteQueriesEXT(1, &resource->gl_read_lock_query_id));
+ gl->DeleteQueriesEXT(1, &resource->gl_read_lock_query_id);
}
if (resource->gl_pixel_buffer_id) {
- DCHECK(resource->origin == Resource::Internal);
+ DCHECK(resource->origin == Resource::INTERNAL);
GLES2Interface* gl = ContextGL();
DCHECK(gl);
- GLC(gl, gl->DeleteBuffers(1, &resource->gl_pixel_buffer_id));
+ gl->DeleteBuffers(1, &resource->gl_pixel_buffer_id);
}
- if (resource->origin == Resource::External) {
+ if (resource->origin == Resource::EXTERNAL) {
DCHECK(resource->mailbox.IsValid());
GLuint sync_point = resource->mailbox.sync_point();
- if (resource->type == GLTexture) {
+ if (resource->type == RESOURCE_TYPE_GL_TEXTURE) {
DCHECK(resource->mailbox.IsTexture());
lost_resource |= lost_output_surface_;
GLES2Interface* gl = ContextGL();
DCHECK(gl);
if (resource->gl_id) {
- GLC(gl, gl->DeleteTextures(1, &resource->gl_id));
+ gl->DeleteTextures(1, &resource->gl_id);
resource->gl_id = 0;
if (!lost_resource)
sync_point = gl->InsertSyncPointCHROMIUM();
}
} else {
DCHECK(resource->mailbox.IsSharedMemory());
- base::SharedMemory* shared_memory = resource->mailbox.shared_memory();
- if (resource->pixels && shared_memory) {
- DCHECK(shared_memory->memory() == resource->pixels);
- resource->pixels = NULL;
- delete resource->shared_bitmap;
- resource->shared_bitmap = NULL;
- }
+ resource->shared_bitmap = nullptr;
+ resource->pixels = nullptr;
}
resource->release_callback_impl.Run(
sync_point, lost_resource, blocking_main_thread_task_runner_);
@@ -713,22 +671,22 @@ void ResourceProvider::DeleteResourceInternal(ResourceMap::iterator it,
if (resource->gl_id) {
GLES2Interface* gl = ContextGL();
DCHECK(gl);
- GLC(gl, gl->DeleteTextures(1, &resource->gl_id));
+ gl->DeleteTextures(1, &resource->gl_id);
resource->gl_id = 0;
}
if (resource->shared_bitmap) {
- DCHECK(resource->origin != Resource::External);
- DCHECK_EQ(Bitmap, resource->type);
+ DCHECK(resource->origin != Resource::EXTERNAL);
+ DCHECK_EQ(RESOURCE_TYPE_BITMAP, resource->type);
delete resource->shared_bitmap;
resource->pixels = NULL;
}
if (resource->pixels) {
- DCHECK(resource->origin == Resource::Internal);
+ DCHECK(resource->origin == Resource::INTERNAL);
delete[] resource->pixels;
resource->pixels = NULL;
}
if (resource->gpu_memory_buffer) {
- DCHECK(resource->origin == Resource::Internal);
+ DCHECK(resource->origin == Resource::INTERNAL);
delete resource->gpu_memory_buffer;
resource->gpu_memory_buffer = NULL;
}
@@ -748,12 +706,12 @@ void ResourceProvider::SetPixels(ResourceId id,
Resource* resource = GetResource(id);
DCHECK(!resource->locked_for_write);
DCHECK(!resource->lock_for_read_count);
- DCHECK(resource->origin == Resource::Internal);
+ DCHECK(resource->origin == Resource::INTERNAL);
DCHECK_EQ(resource->exported_count, 0);
DCHECK(ReadLockFenceHasPassed(resource));
LazyAllocate(resource);
- if (resource->type == GLTexture) {
+ if (resource->type == RESOURCE_TYPE_GL_TEXTURE) {
DCHECK(resource->gl_id);
DCHECK(!resource->pending_set_pixels);
DCHECK_EQ(resource->target, static_cast<GLenum>(GL_TEXTURE_2D));
@@ -768,7 +726,7 @@ void ResourceProvider::SetPixels(ResourceId id,
resource->format,
resource->size);
} else {
- DCHECK_EQ(Bitmap, resource->type);
+ DCHECK_EQ(RESOURCE_TYPE_BITMAP, resource->type);
DCHECK(resource->allocated);
DCHECK_EQ(RGBA_8888, resource->format);
DCHECK(source_rect.x() >= image_rect.x());
@@ -782,9 +740,57 @@ void ResourceProvider::SetPixels(ResourceId id,
image += source_offset.y() * image_row_bytes + source_offset.x() * 4;
ScopedWriteLockSoftware lock(this, id);
- SkCanvas* dest = lock.sk_canvas();
- dest->writePixels(
- source_info, image, image_row_bytes, dest_offset.x(), dest_offset.y());
+ SkCanvas dest(lock.sk_bitmap());
+ dest.writePixels(source_info, image, image_row_bytes, dest_offset.x(),
+ dest_offset.y());
+ }
+}
+
+void ResourceProvider::CopyToResource(ResourceId id,
+ const uint8_t* image,
+ const gfx::Size& image_size) {
+ Resource* resource = GetResource(id);
+ DCHECK(!resource->locked_for_write);
+ DCHECK(!resource->lock_for_read_count);
+ DCHECK(resource->origin == Resource::INTERNAL);
+ DCHECK_EQ(resource->exported_count, 0);
+ DCHECK(ReadLockFenceHasPassed(resource));
+ LazyAllocate(resource);
+
+ DCHECK_EQ(image_size.width(), resource->size.width());
+ DCHECK_EQ(image_size.height(), resource->size.height());
+
+ if (resource->type == RESOURCE_TYPE_BITMAP) {
+ DCHECK_EQ(RESOURCE_TYPE_BITMAP, resource->type);
+ DCHECK(resource->allocated);
+ DCHECK_EQ(RGBA_8888, resource->format);
+ SkImageInfo source_info =
+ SkImageInfo::MakeN32Premul(image_size.width(), image_size.height());
+ size_t image_stride = image_size.width() * 4;
+
+ ScopedWriteLockSoftware lock(this, id);
+ SkCanvas dest(lock.sk_bitmap());
+ dest.writePixels(source_info, image, image_stride, 0, 0);
+ } else {
+ DCHECK(resource->gl_id);
+ DCHECK(!resource->pending_set_pixels);
+ DCHECK_EQ(resource->target, static_cast<GLenum>(GL_TEXTURE_2D));
+ GLES2Interface* gl = ContextGL();
+ DCHECK(gl);
+ DCHECK(texture_uploader_.get());
+ gl->BindTexture(GL_TEXTURE_2D, resource->gl_id);
+
+ if (resource->format == ETC1) {
+ size_t num_bytes = static_cast<size_t>(image_size.width()) *
+ image_size.height() * BitsPerPixel(ETC1) / 8;
+ gl->CompressedTexImage2D(GL_TEXTURE_2D, 0, GLInternalFormat(ETC1),
+ image_size.width(), image_size.height(), 0,
+ num_bytes, image);
+ } else {
+ gl->TexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image_size.width(),
+ image_size.height(), GLDataFormat(resource->format),
+ GLDataType(resource->format), image);
+ }
}
}
@@ -847,10 +853,20 @@ base::TimeTicks ResourceProvider::EstimatedUploadCompletionTime(
return gfx::FrameTime::Now() + upload_one_texture_time * total_uploads;
}
+ResourceProvider::Resource* ResourceProvider::InsertResource(
+ ResourceId id,
+ const Resource& resource) {
+ std::pair<ResourceMap::iterator, bool> result =
+ resources_.insert(ResourceMap::value_type(id, resource));
+ DCHECK(result.second);
+ return &result.first->second;
+}
+
ResourceProvider::Resource* ResourceProvider::GetResource(ResourceId id) {
DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(id);
ResourceMap::iterator it = resources_.find(id);
- CHECK(it != resources_.end());
+ DCHECK(it != resources_.end());
return &it->second;
}
@@ -866,8 +882,8 @@ const ResourceProvider::Resource* ResourceProvider::LockForRead(ResourceId id) {
LazyCreate(resource);
- if (resource->type == GLTexture && !resource->gl_id) {
- DCHECK(resource->origin != Resource::Internal);
+ if (resource->type == RESOURCE_TYPE_GL_TEXTURE && !resource->gl_id) {
+ DCHECK(resource->origin != Resource::INTERNAL);
DCHECK(resource->mailbox.IsTexture());
// Mailbox sync_points must be processed by a call to
@@ -876,11 +892,8 @@ const ResourceProvider::Resource* ResourceProvider::LockForRead(ResourceId id) {
GLES2Interface* gl = ContextGL();
DCHECK(gl);
- 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()));
+ resource->gl_id = gl->CreateAndConsumeTextureCHROMIUM(
+ resource->mailbox.target(), resource->mailbox.name());
}
if (!resource->pixels && resource->has_shared_bitmap_id &&
@@ -916,12 +929,12 @@ void ResourceProvider::UnlockForRead(ResourceId id) {
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);
+ DeleteResourceInternal(it, NORMAL);
} else {
ChildMap::iterator child_it = children_.find(resource->child_id);
ResourceIdArray unused;
unused.push_back(id);
- DeleteAndReturnUnusedResourcesToChild(child_it, Normal, unused);
+ DeleteAndReturnUnusedResourcesToChild(child_it, NORMAL, unused);
}
}
}
@@ -937,14 +950,14 @@ ResourceProvider::Resource* ResourceProvider::LockForWrite(ResourceId id) {
bool ResourceProvider::CanLockForWrite(ResourceId id) {
Resource* resource = GetResource(id);
return !resource->locked_for_write && !resource->lock_for_read_count &&
- !resource->exported_count && resource->origin == Resource::Internal &&
+ !resource->exported_count && resource->origin == Resource::INTERNAL &&
!resource->lost && ReadLockFenceHasPassed(resource);
}
void ResourceProvider::UnlockForWrite(ResourceProvider::Resource* resource) {
DCHECK(resource->locked_for_write);
DCHECK_EQ(resource->exported_count, 0);
- DCHECK(resource->origin == Resource::Internal);
+ DCHECK(resource->origin == Resource::INTERNAL);
resource->locked_for_write = false;
}
@@ -953,8 +966,8 @@ ResourceProvider::ScopedReadLockGL::ScopedReadLockGL(
ResourceProvider::ResourceId resource_id)
: resource_provider_(resource_provider),
resource_id_(resource_id),
- texture_id_(resource_provider->LockForRead(resource_id)->gl_id) {
- DCHECK(texture_id_);
+ resource_(resource_provider->LockForRead(resource_id)) {
+ DCHECK(resource_);
}
ResourceProvider::ScopedReadLockGL::~ScopedReadLockGL() {
@@ -1026,7 +1039,6 @@ ResourceProvider::ScopedWriteLockSoftware::ScopedWriteLockSoftware(
resource_(resource_provider->LockForWrite(resource_id)) {
ResourceProvider::PopulateSkBitmapWithResource(&sk_bitmap_, resource_);
DCHECK(valid());
- sk_canvas_.reset(new SkCanvas(sk_bitmap_));
}
ResourceProvider::ScopedWriteLockSoftware::~ScopedWriteLockSoftware() {
@@ -1043,7 +1055,7 @@ ResourceProvider::ScopedWriteLockGpuMemoryBuffer::
gpu_memory_buffer_(nullptr),
size_(resource_->size),
format_(resource_->format) {
- DCHECK_EQ(GLTexture, resource_->type);
+ DCHECK_EQ(RESOURCE_TYPE_GL_TEXTURE, resource_->type);
std::swap(gpu_memory_buffer_, resource_->gpu_memory_buffer);
}
@@ -1058,11 +1070,16 @@ ResourceProvider::ScopedWriteLockGpuMemoryBuffer::
GLES2Interface* gl = resource_provider_->ContextGL();
DCHECK(gl);
- resource_->image_id =
- gl->CreateImageCHROMIUM(gpu_memory_buffer_->AsClientBuffer(),
- size_.width(),
- size_.height(),
- GL_RGBA);
+#if defined(OS_CHROMEOS)
+ // TODO(reveman): GL_COMMANDS_ISSUED_CHROMIUM is used for synchronization
+ // on ChromeOS to avoid some performance issues. This only works with
+ // shared memory backed buffers. crbug.com/436314
+ DCHECK_EQ(gpu_memory_buffer_->GetHandle().type, gfx::SHARED_MEMORY_BUFFER);
+#endif
+
+ resource_->image_id = gl->CreateImageCHROMIUM(
+ gpu_memory_buffer_->AsClientBuffer(), size_.width(), size_.height(),
+ GLInternalFormat(resource_->format));
}
std::swap(resource_->gpu_memory_buffer, gpu_memory_buffer_);
@@ -1092,48 +1109,56 @@ ResourceProvider::ScopedWriteLockGr::ScopedWriteLockGr(
ResourceProvider::ResourceId resource_id)
: resource_provider_(resource_provider),
resource_(resource_provider->LockForWrite(resource_id)) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ resource_provider_->LazyAllocate(resource_);
}
ResourceProvider::ScopedWriteLockGr::~ScopedWriteLockGr() {
DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(resource_->locked_for_write);
resource_provider_->UnlockForWrite(resource_);
}
-SkSurface* ResourceProvider::ScopedWriteLockGr::GetSkSurface(
- bool use_distance_field_text) {
- DCHECK(thread_checker_.CalledOnValidThread());
+void ResourceProvider::ScopedWriteLockGr::InitSkSurface(
+ bool use_distance_field_text,
+ bool can_use_lcd_text,
+ int msaa_sample_count) {
DCHECK(resource_->locked_for_write);
- // If the surface doesn't exist, or doesn't have the correct dff setting,
- // recreate the surface within the resource.
- if (!resource_->sk_surface ||
- use_distance_field_text !=
- resource_->sk_surface->props().isUseDistanceFieldFonts()) {
- class GrContext* gr_context = resource_provider_->GrContext();
- // TODO(alokp): Implement TestContextProvider::GrContext().
- if (!gr_context)
- return nullptr;
-
- resource_provider_->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));
- if (!gr_texture)
- return nullptr;
- 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));
+ 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;
+ desc.fSampleCnt = msaa_sample_count;
+
+ bool use_worker_context = true;
+ class GrContext* gr_context =
+ resource_provider_->GrContext(use_worker_context);
+ skia::RefPtr<GrTexture> gr_texture =
+ skia::AdoptRef(gr_context->textureProvider()->wrapBackendTexture(desc));
+ if (gr_texture) {
+ uint32_t flags = use_distance_field_text
+ ? SkSurfaceProps::kUseDistanceFieldFonts_Flag
+ : 0;
+ // Use unknown pixel geometry to disable LCD text.
+ SkSurfaceProps surface_props(flags, kUnknown_SkPixelGeometry);
+ if (can_use_lcd_text) {
+ // LegacyFontHost will get LCD text and skia figures out what type to use.
+ surface_props =
+ SkSurfaceProps(flags, SkSurfaceProps::kLegacyFontHost_InitType);
+ }
+ sk_surface_ = skia::AdoptRef(SkSurface::NewRenderTargetDirect(
+ gr_texture->asRenderTarget(), &surface_props));
+ return;
}
- return resource_->sk_surface.get();
+ sk_surface_.clear();
+}
+
+void ResourceProvider::ScopedWriteLockGr::ReleaseSkSurface() {
+ sk_surface_.clear();
}
ResourceProvider::SynchronousFence::SynchronousFence(
@@ -1171,6 +1196,7 @@ ResourceProvider::ResourceProvider(
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
BlockingTaskRunner* blocking_main_thread_task_runner,
int highp_threshold_min,
+ ResourceType default_resource_type,
bool use_rgba_4444_texture_format,
size_t id_allocation_chunk_size)
: output_surface_(output_surface),
@@ -1181,11 +1207,12 @@ ResourceProvider::ResourceProvider(
highp_threshold_min_(highp_threshold_min),
next_id_(1),
next_child_(1),
- default_resource_type_(InvalidType),
+ default_resource_type_(default_resource_type),
use_texture_storage_ext_(false),
use_texture_format_bgra_(false),
use_texture_usage_hint_(false),
use_compressed_texture_etc1_(false),
+ yuv_resource_format_(LUMINANCE_8),
max_texture_size_(0),
best_texture_format_(RGBA_8888),
use_rgba_4444_texture_format_(use_rgba_4444_texture_format),
@@ -1197,11 +1224,7 @@ ResourceProvider::ResourceProvider(
void ResourceProvider::InitializeSoftware() {
DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK_NE(Bitmap, default_resource_type_);
-
- CleanUpGLIfNeeded();
-
- default_resource_type_ = Bitmap;
+ DCHECK_EQ(default_resource_type_, RESOURCE_TYPE_BITMAP);
// Pick an arbitrary limit here similar to what hardware might.
max_texture_size_ = 16 * 1024;
best_texture_format_ = RGBA_8888;
@@ -1209,13 +1232,11 @@ void ResourceProvider::InitializeSoftware() {
void ResourceProvider::InitializeGL() {
DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_EQ(default_resource_type_, RESOURCE_TYPE_GL_TEXTURE);
DCHECK(!texture_uploader_);
- DCHECK_NE(GLTexture, default_resource_type_);
DCHECK(!texture_id_allocator_);
DCHECK(!buffer_id_allocator_);
- default_resource_type_ = GLTexture;
-
const ContextProvider::Capabilities& caps =
output_surface_->context_provider()->ContextCapabilities();
@@ -1224,6 +1245,7 @@ void ResourceProvider::InitializeGL() {
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;
+ yuv_resource_format_ = caps.gpu.texture_rg ? RED_8 : LUMINANCE_8;
use_sync_query_ = caps.gpu.sync_query;
GLES2Interface* gl = ContextGL();
@@ -1231,7 +1253,7 @@ void ResourceProvider::InitializeGL() {
texture_uploader_ = TextureUploader::Create(gl);
max_texture_size_ = 0; // Context expects cleared value.
- GLC(gl, gl->GetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size_));
+ gl->GetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size_);
best_texture_format_ = PlatformColor::BestTextureFormat(use_bgra);
texture_id_allocator_.reset(
@@ -1240,31 +1262,6 @@ void ResourceProvider::InitializeGL() {
new BufferIdAllocator(gl, id_allocation_chunk_size_));
}
-void ResourceProvider::CleanUpGLIfNeeded() {
- GLES2Interface* gl = ContextGL();
- if (default_resource_type_ != GLTexture) {
- // We are not in GL mode, but double check before returning.
- DCHECK(!gl);
- DCHECK(!texture_uploader_);
- return;
- }
-
- 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_ = nullptr;
- texture_id_allocator_ = nullptr;
- buffer_id_allocator_ = nullptr;
- gl->Finish();
-}
-
int ResourceProvider::CreateChild(const ReturnCallback& return_callback) {
DCHECK(thread_checker_.CalledOnValidThread());
@@ -1276,10 +1273,16 @@ int ResourceProvider::CreateChild(const ReturnCallback& return_callback) {
return child;
}
+void ResourceProvider::SetChildNeedsSyncPoints(int child_id, bool needs) {
+ ChildMap::iterator it = children_.find(child_id);
+ DCHECK(it != children_.end());
+ it->second.needs_sync_points = needs;
+}
+
void ResourceProvider::DestroyChild(int child_id) {
ChildMap::iterator it = children_.find(child_id);
DCHECK(it != children_.end());
- DestroyChildInternal(it, Normal);
+ DestroyChildInternal(it, NORMAL);
}
void ResourceProvider::DestroyChildInternal(ChildMap::iterator it,
@@ -1287,7 +1290,7 @@ void ResourceProvider::DestroyChildInternal(ChildMap::iterator it,
DCHECK(thread_checker_.CalledOnValidThread());
Child& child = it->second;
- DCHECK(style == ForShutdown || !child.marked_for_deletion);
+ DCHECK(style == FOR_SHUTDOWN || !child.marked_for_deletion);
ResourceIdArray resources_for_child;
@@ -1298,8 +1301,6 @@ void ResourceProvider::DestroyChildInternal(ChildMap::iterator it,
resources_for_child.push_back(id);
}
- // If the child is going away, don't consider any resources in use.
- child.in_use_resources.clear();
child.marked_for_deletion = true;
DeleteAndReturnUnusedResourcesToChild(it, style, resources_for_child);
@@ -1329,7 +1330,8 @@ void ResourceProvider::PrepareSendToParent(const ResourceIdArray& resources,
++resources_.find(*it)->second.exported_count;
list->push_back(resource);
}
- if (need_sync_point) {
+ if (need_sync_point &&
+ output_surface_->capabilities().delegated_sync_points_required) {
GLuint sync_point = gl->InsertSyncPointCHROMIUM();
for (TransferableResourceArray::iterator it = list->begin();
it != list->end();
@@ -1352,9 +1354,9 @@ 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()) {
- Resource& resource = resources_[resource_in_map_it->second];
- resource.marked_for_deletion = false;
- resource.imported_count++;
+ Resource* resource = GetResource(resource_in_map_it->second);
+ resource->marked_for_deletion = false;
+ resource->imported_count++;
continue;
}
@@ -1369,32 +1371,27 @@ void ResourceProvider::ReceiveFromChild(
}
ResourceId local_id = next_id_++;
- Resource& resource = resources_[local_id];
+ Resource* resource = nullptr;
if (it->is_software) {
- resource = Resource(it->mailbox_holder.mailbox,
- it->size,
- Resource::Delegated,
- GL_LINEAR,
- it->is_repeated ? GL_REPEAT : GL_CLAMP_TO_EDGE);
+ resource = InsertResource(
+ local_id,
+ Resource(it->mailbox_holder.mailbox, it->size, Resource::DELEGATED,
+ GL_LINEAR, it->is_repeated ? GL_REPEAT : GL_CLAMP_TO_EDGE));
} else {
- resource = Resource(0,
- it->size,
- Resource::Delegated,
- it->mailbox_holder.texture_target,
- it->filter,
- 0,
- it->is_repeated ? GL_REPEAT : GL_CLAMP_TO_EDGE,
- TextureHintImmutable,
- it->format);
- resource.mailbox = TextureMailbox(it->mailbox_holder.mailbox,
- it->mailbox_holder.texture_target,
- it->mailbox_holder.sync_point);
+ resource = InsertResource(
+ local_id, Resource(0, it->size, Resource::DELEGATED,
+ it->mailbox_holder.texture_target, it->filter, 0,
+ it->is_repeated ? GL_REPEAT : GL_CLAMP_TO_EDGE,
+ TEXTURE_HINT_IMMUTABLE, it->format));
+ resource->mailbox = TextureMailbox(it->mailbox_holder.mailbox,
+ it->mailbox_holder.texture_target,
+ it->mailbox_holder.sync_point);
}
- resource.child_id = child;
+ resource->child_id = child;
// Don't allocate a texture for a child.
- resource.allocated = true;
- resource.imported_count = 1;
- resource.allow_overlay = it->allow_overlay;
+ resource->allocated = true;
+ resource->imported_count = 1;
+ resource->allow_overlay = it->allow_overlay;
child_info.parent_to_child_map[local_id] = it->id;
child_info.child_to_parent_map[it->id] = local_id;
}
@@ -1402,46 +1399,24 @@ void ResourceProvider::ReceiveFromChild(
void ResourceProvider::DeclareUsedResourcesFromChild(
int child,
- const ResourceIdArray& resources_from_child) {
+ const ResourceIdSet& resources_from_child) {
DCHECK(thread_checker_.CalledOnValidThread());
ChildMap::iterator child_it = children_.find(child);
DCHECK(child_it != children_.end());
Child& child_info = child_it->second;
DCHECK(!child_info.marked_for_deletion);
- child_info.in_use_resources.clear();
-
- for (size_t i = 0; i < resources_from_child.size(); ++i) {
- ResourceIdMap::iterator it =
- child_info.child_to_parent_map.find(resources_from_child[i]);
- 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);
- }
ResourceIdArray unused;
for (ResourceIdMap::iterator it = child_info.child_to_parent_map.begin();
it != child_info.child_to_parent_map.end();
++it) {
ResourceId local_id = it->second;
- bool resource_is_in_use = child_info.in_use_resources.count(local_id) > 0;
+ bool resource_is_in_use = resources_from_child.count(it->first) > 0;
if (!resource_is_in_use)
unused.push_back(local_id);
}
- DeleteAndReturnUnusedResourcesToChild(child_it, Normal, unused);
-}
-
-// static
-bool ResourceProvider::CompareResourceMapIteratorsByChildId(
- const std::pair<ReturnedResource, ResourceMap::iterator>& a,
- const std::pair<ReturnedResource, ResourceMap::iterator>& b) {
- const ResourceMap::iterator& a_it = a.second;
- const ResourceMap::iterator& b_it = b.second;
- const Resource& a_resource = a_it->second;
- const Resource& b_resource = b_it->second;
- return a_resource.child_id < b_resource.child_id;
+ DeleteAndReturnUnusedResourcesToChild(child_it, NORMAL, unused);
}
void ResourceProvider::ReceiveReturnsFromParent(
@@ -1449,36 +1424,16 @@ void ResourceProvider::ReceiveReturnsFromParent(
DCHECK(thread_checker_.CalledOnValidThread());
GLES2Interface* gl = ContextGL();
- int child_id = 0;
- ResourceIdArray resources_for_child;
-
- std::vector<std::pair<ReturnedResource, ResourceMap::iterator>>
- sorted_resources;
+ base::hash_map<int, ResourceIdArray> resources_for_child;
- for (ReturnedResourceArray::const_iterator it = resources.begin();
- it != resources.end();
- ++it) {
- ResourceId local_id = it->id;
+ for (const ReturnedResource& returned : resources) {
+ ResourceId local_id = returned.id;
ResourceMap::iterator map_iterator = resources_.find(local_id);
-
// Resource was already lost (e.g. it belonged to a child that was
// destroyed).
if (map_iterator == resources_.end())
continue;
- sorted_resources.push_back(
- std::pair<ReturnedResource, ResourceMap::iterator>(*it, map_iterator));
- }
-
- std::sort(sorted_resources.begin(),
- sorted_resources.end(),
- CompareResourceMapIteratorsByChildId);
-
- ChildMap::iterator child_it = children_.end();
- for (size_t i = 0; i < sorted_resources.size(); ++i) {
- ReturnedResource& returned = sorted_resources[i].first;
- ResourceMap::iterator& map_iterator = sorted_resources[i].second;
- ResourceId local_id = map_iterator->first;
Resource* resource = &map_iterator->second;
CHECK_GE(resource->exported_count, returned.count);
@@ -1497,9 +1452,9 @@ void ResourceProvider::ReceiveReturnsFromParent(
if (returned.sync_point) {
DCHECK(!resource->has_shared_bitmap_id);
- if (resource->origin == Resource::Internal) {
+ if (resource->origin == Resource::INTERNAL) {
DCHECK(resource->gl_id);
- GLC(gl, gl->WaitSyncPointCHROMIUM(returned.sync_point));
+ gl->WaitSyncPointCHROMIUM(returned.sync_point);
} else {
DCHECK(!resource->gl_id);
resource->mailbox.set_sync_point(returned.sync_point);
@@ -1511,33 +1466,18 @@ void ResourceProvider::ReceiveReturnsFromParent(
if (!resource->child_id) {
// The resource belongs to this ResourceProvider, so it can be destroyed.
- DeleteResourceInternal(map_iterator, Normal);
+ DeleteResourceInternal(map_iterator, NORMAL);
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) {
- DCHECK_NE(resources_for_child.size(), 0u);
- DCHECK(child_it != children_.end());
- DeleteAndReturnUnusedResourcesToChild(
- child_it, Normal, resources_for_child);
- resources_for_child.clear();
- }
-
- child_it = children_.find(resource->child_id);
- DCHECK(child_it != children_.end());
- child_id = resource->child_id;
- }
- resources_for_child.push_back(local_id);
+ DCHECK(resource->origin == Resource::DELEGATED);
+ resources_for_child[resource->child_id].push_back(local_id);
}
- if (child_id) {
- DCHECK_NE(resources_for_child.size(), 0u);
+ for (const auto& children : resources_for_child) {
+ ChildMap::iterator child_it = children_.find(children.first);
DCHECK(child_it != children_.end());
- DeleteAndReturnUnusedResourcesToChild(
- child_it, Normal, resources_for_child);
+ DeleteAndReturnUnusedResourcesToChild(child_it, NORMAL, children.second);
}
}
@@ -1547,7 +1487,7 @@ void ResourceProvider::TransferResource(GLES2Interface* gl,
Resource* source = GetResource(id);
DCHECK(!source->locked_for_write);
DCHECK(!source->lock_for_read_count);
- DCHECK(source->origin != Resource::External || source->mailbox.IsValid());
+ DCHECK(source->origin != Resource::EXTERNAL || source->mailbox.IsValid());
DCHECK(source->allocated);
resource->id = id;
resource->format = source->format;
@@ -1557,35 +1497,31 @@ void ResourceProvider::TransferResource(GLES2Interface* gl,
resource->is_repeated = (source->wrap_mode == GL_REPEAT);
resource->allow_overlay = source->allow_overlay;
- if (source->type == Bitmap) {
+ if (source->type == RESOURCE_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));
+ DCHECK(source->origin == Resource::INTERNAL);
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.
- GLC(gl, gl->GenMailboxCHROMIUM(resource->mailbox_holder.mailbox.name));
- GLC(gl,
- gl->ProduceTextureCHROMIUM(resource->mailbox_holder.texture_target,
- resource->mailbox_holder.mailbox.name));
+ gl->GenMailboxCHROMIUM(resource->mailbox_holder.mailbox.name);
+ gl->ProduceTextureDirectCHROMIUM(source->gl_id,
+ 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));
+ DCHECK(source->origin == Resource::INTERNAL);
+ gl->BindTexture(resource->mailbox_holder.texture_target, source->gl_id);
BindImageForSampling(source);
}
// This is either an external resource, or a compositor resource that we
@@ -1620,16 +1556,16 @@ void ResourceProvider::DeleteAndReturnUnusedResourcesToChild(
Resource& resource = it->second;
DCHECK(!resource.locked_for_write);
- DCHECK_EQ(0u, child_info->in_use_resources.count(local_id));
DCHECK(child_info->parent_to_child_map.count(local_id));
ResourceId child_id = child_info->parent_to_child_map[local_id];
DCHECK(child_info->child_to_parent_map.count(child_id));
bool is_lost =
- resource.lost || (resource.type == GLTexture && lost_output_surface_);
+ resource.lost ||
+ (resource.type == RESOURCE_TYPE_GL_TEXTURE && lost_output_surface_);
if (resource.exported_count > 0 || resource.lock_for_read_count > 0) {
- if (style != ForShutdown) {
+ if (style != FOR_SHUTDOWN) {
// Defer this until we receive the resource back from the parent or
// the read lock is released.
resource.marked_for_deletion = true;
@@ -1644,21 +1580,17 @@ void ResourceProvider::DeleteAndReturnUnusedResourcesToChild(
DCHECK(resource.target);
DCHECK(resource.gl_id);
- GLC(gl, gl->BindTexture(resource.target, resource.gl_id));
- GLC(gl,
- gl->TexParameteri(resource.target,
- GL_TEXTURE_MIN_FILTER,
- resource.original_filter));
- GLC(gl,
- gl->TexParameteri(resource.target,
- GL_TEXTURE_MAG_FILTER,
- resource.original_filter));
+ gl->BindTexture(resource.target, resource.gl_id);
+ gl->TexParameteri(resource.target, GL_TEXTURE_MIN_FILTER,
+ resource.original_filter);
+ gl->TexParameteri(resource.target, GL_TEXTURE_MAG_FILTER,
+ resource.original_filter);
}
ReturnedResource returned;
returned.id = child_id;
returned.sync_point = resource.mailbox.sync_point();
- if (!returned.sync_point && resource.type == GLTexture)
+ if (!returned.sync_point && resource.type == RESOURCE_TYPE_GL_TEXTURE)
need_sync_point = true;
returned.count = resource.imported_count;
returned.lost = is_lost;
@@ -1669,7 +1601,7 @@ void ResourceProvider::DeleteAndReturnUnusedResourcesToChild(
resource.imported_count = 0;
DeleteResourceInternal(it, style);
}
- if (need_sync_point) {
+ if (need_sync_point && child_info->needs_sync_points) {
DCHECK(gl);
GLuint sync_point = gl->InsertSyncPointCHROMIUM();
for (size_t i = 0; i < to_return.size(); ++i) {
@@ -1694,12 +1626,12 @@ void ResourceProvider::AcquirePixelBuffer(ResourceId id) {
"ResourceProvider::AcquirePixelBuffer");
Resource* resource = GetResource(id);
- DCHECK(resource->origin == Resource::Internal);
+ 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);
+ DCHECK_EQ(RESOURCE_TYPE_GL_TEXTURE, resource->type);
GLES2Interface* gl = ContextGL();
DCHECK(gl);
if (!resource->gl_pixel_buffer_id)
@@ -1720,7 +1652,7 @@ void ResourceProvider::ReleasePixelBuffer(ResourceId id) {
"ResourceProvider::ReleasePixelBuffer");
Resource* resource = GetResource(id);
- DCHECK(resource->origin == Resource::Internal);
+ DCHECK(resource->origin == Resource::INTERNAL);
DCHECK_EQ(resource->exported_count, 0);
DCHECK(!resource->image_id);
@@ -1736,7 +1668,7 @@ void ResourceProvider::ReleasePixelBuffer(ResourceId id) {
resource->locked_for_write = false;
}
- DCHECK_EQ(GLTexture, resource->type);
+ DCHECK_EQ(RESOURCE_TYPE_GL_TEXTURE, resource->type);
if (!resource->gl_pixel_buffer_id)
return;
GLES2Interface* gl = ContextGL();
@@ -1753,12 +1685,12 @@ uint8_t* ResourceProvider::MapPixelBuffer(ResourceId id, int* stride) {
"ResourceProvider::MapPixelBuffer");
Resource* resource = GetResource(id);
- DCHECK(resource->origin == Resource::Internal);
+ DCHECK(resource->origin == Resource::INTERNAL);
DCHECK_EQ(resource->exported_count, 0);
DCHECK(!resource->image_id);
*stride = 0;
- DCHECK_EQ(GLTexture, resource->type);
+ DCHECK_EQ(RESOURCE_TYPE_GL_TEXTURE, resource->type);
GLES2Interface* gl = ContextGL();
DCHECK(gl);
DCHECK(resource->gl_pixel_buffer_id);
@@ -1777,11 +1709,11 @@ void ResourceProvider::UnmapPixelBuffer(ResourceId id) {
"ResourceProvider::UnmapPixelBuffer");
Resource* resource = GetResource(id);
- DCHECK(resource->origin == Resource::Internal);
+ DCHECK(resource->origin == Resource::INTERNAL);
DCHECK_EQ(resource->exported_count, 0);
DCHECK(!resource->image_id);
- DCHECK_EQ(GLTexture, resource->type);
+ DCHECK_EQ(RESOURCE_TYPE_GL_TEXTURE, resource->type);
GLES2Interface* gl = ContextGL();
DCHECK(gl);
DCHECK(resource->gl_pixel_buffer_id);
@@ -1804,10 +1736,10 @@ GLenum ResourceProvider::BindForSampling(ResourceId resource_id,
ScopedSetActiveTexture scoped_active_tex(gl, unit);
GLenum target = resource->target;
- GLC(gl, gl->BindTexture(target, resource->gl_id));
+ gl->BindTexture(target, resource->gl_id);
if (filter != resource->filter) {
- GLC(gl, gl->TexParameteri(target, GL_TEXTURE_MIN_FILTER, filter));
- GLC(gl, gl->TexParameteri(target, GL_TEXTURE_MAG_FILTER, filter));
+ gl->TexParameteri(target, GL_TEXTURE_MIN_FILTER, filter);
+ gl->TexParameteri(target, GL_TEXTURE_MAG_FILTER, filter);
resource->filter = filter;
}
@@ -1825,7 +1757,7 @@ void ResourceProvider::BeginSetPixels(ResourceId id) {
DCHECK(!resource->pending_set_pixels);
LazyCreate(resource);
- DCHECK(resource->origin == Resource::Internal);
+ DCHECK(resource->origin == Resource::INTERNAL);
DCHECK(resource->gl_id || resource->allocated);
DCHECK(ReadLockFenceHasPassed(resource));
DCHECK(!resource->image_id);
@@ -1834,7 +1766,7 @@ void ResourceProvider::BeginSetPixels(ResourceId id) {
resource->allocated = true;
LockForWrite(id);
- DCHECK_EQ(GLTexture, resource->type);
+ DCHECK_EQ(RESOURCE_TYPE_GL_TEXTURE, resource->type);
DCHECK(resource->gl_id);
GLES2Interface* gl = ContextGL();
DCHECK(gl);
@@ -1887,9 +1819,9 @@ void ResourceProvider::ForceSetPixelsToComplete(ResourceId id) {
if (resource->gl_id) {
GLES2Interface* gl = ContextGL();
- GLC(gl, gl->BindTexture(GL_TEXTURE_2D, resource->gl_id));
- GLC(gl, gl->WaitAsyncTexImage2DCHROMIUM(GL_TEXTURE_2D));
- GLC(gl, gl->BindTexture(GL_TEXTURE_2D, 0));
+ gl->BindTexture(GL_TEXTURE_2D, resource->gl_id);
+ gl->WaitAsyncTexImage2DCHROMIUM(GL_TEXTURE_2D);
+ gl->BindTexture(GL_TEXTURE_2D, 0);
}
resource->set_pixels_completion_forced = true;
@@ -1936,14 +1868,15 @@ GLenum ResourceProvider::TargetForTesting(ResourceId id) {
}
void ResourceProvider::LazyCreate(Resource* resource) {
- if (resource->type != GLTexture || resource->origin != Resource::Internal)
+ if (resource->type != RESOURCE_TYPE_GL_TEXTURE ||
+ resource->origin != Resource::INTERNAL)
return;
if (resource->gl_id)
return;
DCHECK(resource->texture_pool);
- DCHECK(resource->origin == Resource::Internal);
+ DCHECK(resource->origin == Resource::INTERNAL);
DCHECK(!resource->mailbox.IsValid());
resource->gl_id = texture_id_allocator_->NextId();
@@ -1951,27 +1884,18 @@ void ResourceProvider::LazyCreate(Resource* resource) {
DCHECK(gl);
// 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, resource->original_filter));
- GLC(gl,
- 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_WRAP_T, resource->wrap_mode));
- GLC(gl,
- gl->TexParameteri(
- resource->target, GL_TEXTURE_POOL_CHROMIUM, resource->texture_pool));
- if (use_texture_usage_hint_ && (resource->hint & TextureHintFramebuffer)) {
- GLC(gl,
- gl->TexParameteri(resource->target,
- GL_TEXTURE_USAGE_ANGLE,
- GL_FRAMEBUFFER_ATTACHMENT_ANGLE));
+ gl->BindTexture(resource->target, resource->gl_id);
+ gl->TexParameteri(resource->target, GL_TEXTURE_MIN_FILTER,
+ resource->original_filter);
+ gl->TexParameteri(resource->target, GL_TEXTURE_MAG_FILTER,
+ resource->original_filter);
+ gl->TexParameteri(resource->target, GL_TEXTURE_WRAP_S, resource->wrap_mode);
+ gl->TexParameteri(resource->target, GL_TEXTURE_WRAP_T, resource->wrap_mode);
+ gl->TexParameteri(resource->target, GL_TEXTURE_POOL_CHROMIUM,
+ resource->texture_pool);
+ if (use_texture_usage_hint_ && (resource->hint & TEXTURE_HINT_FRAMEBUFFER)) {
+ gl->TexParameteri(resource->target, GL_TEXTURE_USAGE_ANGLE,
+ GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
}
}
@@ -1991,27 +1915,19 @@ void ResourceProvider::LazyAllocate(Resource* resource) {
gfx::Size& size = resource->size;
DCHECK_EQ(resource->target, static_cast<GLenum>(GL_TEXTURE_2D));
ResourceFormat format = resource->format;
- GLC(gl, gl->BindTexture(GL_TEXTURE_2D, resource->gl_id));
+ gl->BindTexture(GL_TEXTURE_2D, resource->gl_id);
if (use_texture_storage_ext_ &&
IsFormatSupportedForStorage(format, use_texture_format_bgra_) &&
- (resource->hint & TextureHintImmutable)) {
+ (resource->hint & TEXTURE_HINT_IMMUTABLE)) {
GLenum storage_format = TextureToStorageFormat(format);
- GLC(gl,
- gl->TexStorage2DEXT(
- GL_TEXTURE_2D, 1, storage_format, size.width(), size.height()));
+ gl->TexStorage2DEXT(GL_TEXTURE_2D, 1, storage_format, size.width(),
+ size.height());
} else {
// ETC1 does not support preallocation.
if (format != ETC1) {
- GLC(gl,
- gl->TexImage2D(GL_TEXTURE_2D,
- 0,
- GLInternalFormat(format),
- size.width(),
- size.height(),
- 0,
- GLDataFormat(format),
- GLDataType(format),
- NULL));
+ gl->TexImage2D(GL_TEXTURE_2D, 0, GLInternalFormat(format), size.width(),
+ size.height(), 0, GLDataFormat(format), GLDataType(format),
+ NULL);
}
}
}
@@ -2034,19 +1950,19 @@ void ResourceProvider::CopyResource(ResourceId source_id, ResourceId dest_id) {
Resource* source_resource = GetResource(source_id);
DCHECK(!source_resource->lock_for_read_count);
- DCHECK(source_resource->origin == Resource::Internal);
+ DCHECK(source_resource->origin == Resource::INTERNAL);
DCHECK_EQ(source_resource->exported_count, 0);
- DCHECK_EQ(GLTexture, source_resource->type);
+ DCHECK_EQ(RESOURCE_TYPE_GL_TEXTURE, source_resource->type);
DCHECK(source_resource->allocated);
LazyCreate(source_resource);
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(dest_resource->origin == Resource::INTERNAL);
DCHECK_EQ(dest_resource->exported_count, 0);
- DCHECK_EQ(GLTexture, dest_resource->type);
- LazyCreate(dest_resource);
+ DCHECK_EQ(RESOURCE_TYPE_GL_TEXTURE, dest_resource->type);
+ LazyAllocate(dest_resource);
DCHECK_EQ(source_resource->type, dest_resource->type);
DCHECK_EQ(source_resource->format, dest_resource->format);
@@ -2061,23 +1977,31 @@ void ResourceProvider::CopyResource(ResourceId source_id, ResourceId dest_id) {
if (use_sync_query_) {
if (!source_resource->gl_read_lock_query_id)
gl->GenQueriesEXT(1, &source_resource->gl_read_lock_query_id);
+#if defined(OS_CHROMEOS)
+ // TODO(reveman): This avoids a performance problem on some ChromeOS
+ // devices. This needs to be removed to support native GpuMemoryBuffer
+ // implementations. crbug.com/436314
+ gl->BeginQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM,
+ source_resource->gl_read_lock_query_id);
+#else
gl->BeginQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM,
source_resource->gl_read_lock_query_id);
+#endif
}
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));
+ gl->CopySubTextureCHROMIUM(dest_resource->target, source_resource->gl_id,
+ dest_resource->gl_id, 0, 0);
if (source_resource->gl_read_lock_query_id) {
// End query and create a read lock fence that will prevent access to
- // source resource until CopyTextureCHROMIUM command has completed.
+// source resource until CopySubTextureCHROMIUM command has completed.
+#if defined(OS_CHROMEOS)
+ gl->EndQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM);
+#else
gl->EndQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM);
+#endif
source_resource->read_lock_fence = make_scoped_refptr(
- new QueryFence(gl, source_resource->gl_read_lock_query_id));
+ new CopyTextureFence(gl, source_resource->gl_read_lock_query_id));
} else {
// Create a SynchronousFence when CHROMIUM_sync_query extension is missing.
// Try to use one synchronous fence for as many CopyResource operations as
@@ -2094,14 +2018,14 @@ 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)
+ if (resource->type != RESOURCE_TYPE_GL_TEXTURE || 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()));
+ gl->WaitSyncPointCHROMIUM(resource->mailbox.sync_point());
resource->mailbox.set_sync_point(0);
}
@@ -2120,13 +2044,21 @@ GLint ResourceProvider::GetActiveTextureUnit(GLES2Interface* gl) {
return active_unit;
}
+void ResourceProvider::ValidateResource(ResourceId id) const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(id);
+ DCHECK(resources_.find(id) != resources_.end());
+}
+
GLES2Interface* ResourceProvider::ContextGL() const {
ContextProvider* context_provider = output_surface_->context_provider();
return context_provider ? context_provider->ContextGL() : NULL;
}
-class GrContext* ResourceProvider::GrContext() const {
- ContextProvider* context_provider = output_surface_->context_provider();
+class GrContext* ResourceProvider::GrContext(bool worker_context) const {
+ ContextProvider* context_provider =
+ worker_context ? output_surface_->worker_context_provider()
+ : output_surface_->context_provider();
return context_provider ? context_provider->GrContext() : NULL;
}