summaryrefslogtreecommitdiffstats
path: root/cc/resources
diff options
context:
space:
mode:
Diffstat (limited to 'cc/resources')
-rw-r--r--cc/resources/resource_format.cc19
-rw-r--r--cc/resources/resource_format.h2
-rw-r--r--cc/resources/resource_pool.cc5
-rw-r--r--cc/resources/resource_pool.h5
-rw-r--r--cc/resources/resource_pool_unittest.cc13
-rw-r--r--cc/resources/resource_provider.cc156
-rw-r--r--cc/resources/resource_provider.h18
-rw-r--r--cc/resources/resource_provider_unittest.cc134
8 files changed, 293 insertions, 59 deletions
diff --git a/cc/resources/resource_format.cc b/cc/resources/resource_format.cc
index c62ae93..ce9fe7d 100644
--- a/cc/resources/resource_format.cc
+++ b/cc/resources/resource_format.cc
@@ -87,23 +87,4 @@ GLenum GLInternalFormat(ResourceFormat format) {
return GLDataFormat(format);
}
-gfx::BufferFormat BufferFormat(ResourceFormat format) {
- switch (format) {
- case RGBA_8888:
- return gfx::BufferFormat::RGBA_8888;
- case BGRA_8888:
- return gfx::BufferFormat::BGRA_8888;
- case RGBA_4444:
- return gfx::BufferFormat::RGBA_4444;
- case ALPHA_8:
- case LUMINANCE_8:
- case RGB_565:
- case ETC1:
- case RED_8:
- break;
- }
- NOTREACHED();
- return gfx::BufferFormat::RGBA_8888;
-}
-
} // namespace cc
diff --git a/cc/resources/resource_format.h b/cc/resources/resource_format.h
index 79b815f..d910bb0 100644
--- a/cc/resources/resource_format.h
+++ b/cc/resources/resource_format.h
@@ -8,7 +8,6 @@
#include "base/logging.h"
#include "cc/base/cc_export.h"
#include "third_party/skia/include/core/SkBitmap.h"
-#include "ui/gfx/gpu_memory_buffer.h"
// TODO(prashant.n): Including third_party/khronos/GLES2/gl2.h causes
// redefinition errors as macros/functions defined in it conflict with
@@ -36,7 +35,6 @@ CC_EXPORT int BitsPerPixel(ResourceFormat format);
CC_EXPORT GLenum GLDataType(ResourceFormat format);
CC_EXPORT GLenum GLDataFormat(ResourceFormat format);
CC_EXPORT GLenum GLInternalFormat(ResourceFormat format);
-CC_EXPORT gfx::BufferFormat BufferFormat(ResourceFormat format);
} // namespace cc
diff --git a/cc/resources/resource_pool.cc b/cc/resources/resource_pool.cc
index e0e5af3..cdcaa4d 100644
--- a/cc/resources/resource_pool.cc
+++ b/cc/resources/resource_pool.cc
@@ -191,12 +191,15 @@ void ResourcePool::DeleteResource(ScopedResource* resource) {
delete resource;
}
-void ResourcePool::CheckBusyResources() {
+void ResourcePool::CheckBusyResources(bool wait_if_needed) {
ResourceList::iterator it = busy_resources_.begin();
while (it != busy_resources_.end()) {
ScopedResource* resource = it->resource;
+ if (wait_if_needed)
+ resource_provider_->WaitReadLockIfNeeded(resource->id());
+
if (resource_provider_->CanLockForWrite(resource->id())) {
DidFinishUsingResource(resource, it->content_id);
it = busy_resources_.erase(it);
diff --git a/cc/resources/resource_pool.h b/cc/resources/resource_pool.h
index e87e217..e577826 100644
--- a/cc/resources/resource_pool.h
+++ b/cc/resources/resource_pool.h
@@ -41,7 +41,10 @@ class CC_EXPORT ResourcePool : public base::trace_event::MemoryDumpProvider {
size_t max_resource_count);
void ReduceResourceUsage();
- void CheckBusyResources();
+ // This might block if |wait_if_needed| is true and one of the currently
+ // busy resources has a read lock fence that needs to be waited upon before
+ // it can be locked for write again.
+ void CheckBusyResources(bool wait_if_needed);
size_t total_memory_usage_bytes() const { return memory_usage_bytes_; }
size_t acquired_memory_usage_bytes() const {
diff --git a/cc/resources/resource_pool_unittest.cc b/cc/resources/resource_pool_unittest.cc
index f280f49..035b19e 100644
--- a/cc/resources/resource_pool_unittest.cc
+++ b/cc/resources/resource_pool_unittest.cc
@@ -71,7 +71,8 @@ TEST_F(ResourcePoolTest, AccountingSingleResource) {
EXPECT_EQ(1u, resource_pool_->total_resource_count());
EXPECT_EQ(1u, resource_pool_->busy_resource_count());
- resource_pool_->CheckBusyResources();
+ bool wait_if_needed = false;
+ resource_pool_->CheckBusyResources(wait_if_needed);
EXPECT_EQ(resource_bytes, resource_pool_->total_memory_usage_bytes());
EXPECT_EQ(0u, resource_pool_->acquired_memory_usage_bytes());
EXPECT_EQ(1u, resource_pool_->total_resource_count());
@@ -95,25 +96,26 @@ TEST_F(ResourcePoolTest, SimpleResourceReuse) {
gfx::Size size(100, 100);
ResourceFormat format = RGBA_8888;
+ bool wait_if_needed = false;
scoped_ptr<ScopedResource> resource =
resource_pool_->AcquireResource(size, format);
resource_pool_->ReleaseResource(resource.Pass(), 0u);
- resource_pool_->CheckBusyResources();
+ resource_pool_->CheckBusyResources(wait_if_needed);
EXPECT_EQ(1u, resource_provider_->num_resources());
// Same size/format should re-use resource.
resource = resource_pool_->AcquireResource(size, format);
EXPECT_EQ(1u, resource_provider_->num_resources());
resource_pool_->ReleaseResource(resource.Pass(), 0u);
- resource_pool_->CheckBusyResources();
+ resource_pool_->CheckBusyResources(wait_if_needed);
EXPECT_EQ(1u, resource_provider_->num_resources());
// Different size/format should alloate new resource.
resource = resource_pool_->AcquireResource(gfx::Size(50, 50), LUMINANCE_8);
EXPECT_EQ(2u, resource_provider_->num_resources());
resource_pool_->ReleaseResource(resource.Pass(), 0u);
- resource_pool_->CheckBusyResources();
+ resource_pool_->CheckBusyResources(wait_if_needed);
EXPECT_EQ(2u, resource_provider_->num_resources());
}
@@ -125,6 +127,7 @@ TEST_F(ResourcePoolTest, LostResource) {
gfx::Size size(100, 100);
ResourceFormat format = RGBA_8888;
+ bool wait_if_needed = false;
scoped_ptr<ScopedResource> resource =
resource_pool_->AcquireResource(size, format);
@@ -132,7 +135,7 @@ TEST_F(ResourcePoolTest, LostResource) {
resource_provider_->LoseResourceForTesting(resource->id());
resource_pool_->ReleaseResource(resource.Pass(), 0u);
- resource_pool_->CheckBusyResources();
+ resource_pool_->CheckBusyResources(wait_if_needed);
EXPECT_EQ(0u, resource_provider_->num_resources());
}
diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc
index 6129b26..be282b9 100644
--- a/cc/resources/resource_provider.cc
+++ b/cc/resources/resource_provider.cc
@@ -33,6 +33,7 @@
#include "third_party/skia/include/gpu/GrTextureProvider.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/vector2d.h"
+#include "ui/gfx/gpu_memory_buffer.h"
#include "ui/gl/trace_util.h"
using gpu::gles2::GLES2Interface;
@@ -117,6 +118,25 @@ GrPixelConfig ToGrPixelConfig(ResourceFormat format) {
return kSkia8888_GrPixelConfig;
}
+gfx::BufferFormat ToGpuMemoryBufferFormat(ResourceFormat format) {
+ switch (format) {
+ case RGBA_8888:
+ return gfx::BufferFormat::RGBA_8888;
+ case BGRA_8888:
+ return gfx::BufferFormat::BGRA_8888;
+ case RGBA_4444:
+ return gfx::BufferFormat::RGBA_4444;
+ case ALPHA_8:
+ case LUMINANCE_8:
+ case RGB_565:
+ case ETC1:
+ case RED_8:
+ break;
+ }
+ NOTREACHED();
+ return gfx::BufferFormat::RGBA_8888;
+}
+
class ScopedSetActiveTexture {
public:
ScopedSetActiveTexture(GLES2Interface* gl, GLenum unit)
@@ -187,6 +207,46 @@ class BufferIdAllocator : public IdAllocator {
DISALLOW_COPY_AND_ASSIGN(BufferIdAllocator);
};
+// 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:
+ CopyTextureFence(gpu::gles2::GLES2Interface* gl, unsigned query_id)
+ : gl_(gl), query_id_(query_id) {}
+
+ // Overridden from ResourceProvider::Fence:
+ void Set() override {}
+ bool HasPassed() override {
+ unsigned available = 1;
+ gl_->GetQueryObjectuivEXT(
+ query_id_, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
+ if (!available)
+ return false;
+
+ ProcessResult();
+ return true;
+ }
+ void Wait() override {
+ // ProcessResult() will wait for result to become available.
+ ProcessResult();
+ }
+
+ private:
+ ~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(CopyTextureFence);
+};
+
// Generates process-unique IDs to use for tracing a ResourceProvider's
// resources.
base::StaticAtomicSequenceNumber g_next_resource_provider_tracing_id;
@@ -342,12 +402,13 @@ scoped_ptr<ResourceProvider> ResourceProvider::Create(
int highp_threshold_min,
bool use_rgba_4444_texture_format,
size_t id_allocation_chunk_size,
+ bool use_persistent_map_for_gpu_memory_buffers,
const std::vector<unsigned>& use_image_texture_targets) {
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,
- use_image_texture_targets));
+ use_persistent_map_for_gpu_memory_buffers, use_image_texture_targets));
resource_provider->Initialize();
return resource_provider;
}
@@ -938,9 +999,13 @@ gfx::GpuMemoryBuffer*
ResourceProvider::ScopedWriteLockGpuMemoryBuffer::GetGpuMemoryBuffer() {
if (gpu_memory_buffer_)
return gpu_memory_buffer_;
+ gfx::BufferUsage usage =
+ resource_provider_->use_persistent_map_for_gpu_memory_buffers()
+ ? gfx::BufferUsage::PERSISTENT_MAP
+ : gfx::BufferUsage::MAP;
scoped_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer =
gpu_memory_buffer_manager_->AllocateGpuMemoryBuffer(
- size_, BufferFormat(format_), gfx::BufferUsage::MAP);
+ size_, ToGpuMemoryBufferFormat(format_), usage);
gpu_memory_buffer_ = gpu_memory_buffer.release();
return gpu_memory_buffer_;
}
@@ -1032,6 +1097,7 @@ ResourceProvider::ResourceProvider(
int highp_threshold_min,
bool use_rgba_4444_texture_format,
size_t id_allocation_chunk_size,
+ bool use_persistent_map_for_gpu_memory_buffers,
const std::vector<unsigned>& use_image_texture_targets)
: output_surface_(output_surface),
shared_bitmap_manager_(shared_bitmap_manager),
@@ -1053,6 +1119,8 @@ ResourceProvider::ResourceProvider(
use_rgba_4444_texture_format_(use_rgba_4444_texture_format),
id_allocation_chunk_size_(id_allocation_chunk_size),
use_sync_query_(false),
+ use_persistent_map_for_gpu_memory_buffers_(
+ use_persistent_map_for_gpu_memory_buffers),
use_image_texture_targets_(use_image_texture_targets),
tracing_id_(g_next_resource_provider_tracing_id.GetNext()) {
DCHECK(output_surface_->HasClient());
@@ -1788,6 +1856,79 @@ void ResourceProvider::BindImageForSampling(Resource* resource) {
resource->dirty_image = false;
}
+void ResourceProvider::CopyResource(ResourceId source_id,
+ ResourceId dest_id,
+ const gfx::Rect& rect) {
+ TRACE_EVENT0("cc", "ResourceProvider::CopyResource");
+
+ 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_EQ(RESOURCE_TYPE_GL_TEXTURE, source_resource->type);
+ LazyAllocate(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_EQ(dest_resource->exported_count, 0);
+ 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);
+ DCHECK(source_resource->size == dest_resource->size);
+ DCHECK(gfx::Rect(dest_resource->size).Contains(rect));
+
+ 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);
+ }
+ 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->CopySubTextureCHROMIUM(dest_resource->target, source_resource->gl_id,
+ dest_resource->gl_id, rect.x(), rect.y(), rect.x(),
+ rect.y(), rect.width(), rect.height(),
+ false, false, false);
+ if (source_resource->gl_read_lock_query_id) {
+ // End query and create a read lock fence that will prevent access to
+// 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 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
+ // possible as that reduce the number of times we have to synchronize with
+ // the GL.
+ if (!synchronous_fence_.get() || synchronous_fence_->has_synchronized())
+ synchronous_fence_ = make_scoped_refptr(new SynchronousFence(gl));
+ source_resource->read_lock_fence = synchronous_fence_;
+ source_resource->read_lock_fence->Set();
+ }
+}
+
void ResourceProvider::WaitSyncPointIfNeeded(ResourceId id) {
Resource* resource = GetResource(id);
DCHECK_EQ(resource->exported_count, 0);
@@ -1803,6 +1944,15 @@ void ResourceProvider::WaitSyncPointIfNeeded(ResourceId id) {
resource->mailbox.set_sync_point(0);
}
+void ResourceProvider::WaitReadLockIfNeeded(ResourceId id) {
+ Resource* resource = GetResource(id);
+ DCHECK_EQ(resource->exported_count, 0);
+ if (!resource->read_lock_fence.get())
+ return;
+
+ resource->read_lock_fence->Wait();
+}
+
GLint ResourceProvider::GetActiveTextureUnit(GLES2Interface* gl) {
GLint active_unit = 0;
gl->GetIntegerv(GL_ACTIVE_TEXTURE, &active_unit);
@@ -1810,7 +1960,7 @@ GLint ResourceProvider::GetActiveTextureUnit(GLES2Interface* gl) {
}
GLenum ResourceProvider::GetImageTextureTarget(ResourceFormat format) {
- gfx::BufferFormat buffer_format = BufferFormat(format);
+ gfx::BufferFormat buffer_format = ToGpuMemoryBufferFormat(format);
DCHECK_GT(use_image_texture_targets_.size(),
static_cast<size_t>(buffer_format));
return use_image_texture_targets_[static_cast<size_t>(buffer_format)];
diff --git a/cc/resources/resource_provider.h b/cc/resources/resource_provider.h
index 8b7ccd8..324df1b 100644
--- a/cc/resources/resource_provider.h
+++ b/cc/resources/resource_provider.h
@@ -35,7 +35,6 @@
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "ui/gfx/geometry/size.h"
-#include "ui/gfx/gpu_memory_buffer.h"
class GrContext;
@@ -47,6 +46,7 @@ class GLES2Interface;
}
namespace gfx {
+class GpuMemoryBuffer;
class Rect;
class Vector2d;
}
@@ -88,6 +88,7 @@ class CC_EXPORT ResourceProvider
int highp_threshold_min,
bool use_rgba_4444_texture_format,
size_t id_allocation_chunk_size,
+ bool use_persistent_map_for_gpu_memory_buffers,
const std::vector<unsigned>& use_image_texture_targets);
~ResourceProvider() override;
@@ -103,8 +104,8 @@ class CC_EXPORT ResourceProvider
}
ResourceFormat yuv_resource_format() const { return yuv_resource_format_; }
bool use_sync_query() const { return use_sync_query_; }
- gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager() {
- return gpu_memory_buffer_manager_;
+ bool use_persistent_map_for_gpu_memory_buffers() const {
+ return use_persistent_map_for_gpu_memory_buffers_;
}
size_t num_resources() const { return resources_.size(); }
@@ -426,8 +427,15 @@ class CC_EXPORT ResourceProvider
// Indicates if we can currently lock this resource for write.
bool CanLockForWrite(ResourceId id);
+ // Copy |rect| pixels from source to destination.
+ void CopyResource(ResourceId source_id,
+ ResourceId dest_id,
+ const gfx::Rect& rect);
+
void WaitSyncPointIfNeeded(ResourceId id);
+ void WaitReadLockIfNeeded(ResourceId id);
+
static GLint GetActiveTextureUnit(gpu::gles2::GLES2Interface* gl);
OutputSurface* output_surface() { return output_surface_; }
@@ -450,6 +458,7 @@ class CC_EXPORT ResourceProvider
int highp_threshold_min,
bool use_rgba_4444_texture_format,
size_t id_allocation_chunk_size,
+ bool use_persistent_map_for_gpu_memory_buffers,
const std::vector<unsigned>& use_image_texture_targets);
void Initialize();
@@ -605,6 +614,9 @@ class CC_EXPORT ResourceProvider
scoped_ptr<IdAllocator> buffer_id_allocator_;
bool use_sync_query_;
+ bool use_persistent_map_for_gpu_memory_buffers_;
+ // Fence used for CopyResource if CHROMIUM_sync_query is not supported.
+ scoped_refptr<SynchronousFence> synchronous_fence_;
std::vector<unsigned> use_image_texture_targets_;
// A process-unique ID used for disambiguating memory dumps from different
diff --git a/cc/resources/resource_provider_unittest.cc b/cc/resources/resource_provider_unittest.cc
index 7c65b73..4a02e82 100644
--- a/cc/resources/resource_provider_unittest.cc
+++ b/cc/resources/resource_provider_unittest.cc
@@ -422,11 +422,11 @@ class ResourceProviderTest
resource_provider_ = ResourceProvider::Create(
output_surface_.get(), shared_bitmap_manager_.get(),
gpu_memory_buffer_manager_.get(), main_thread_task_runner_.get(), 0,
- false, 1, use_image_texture_targets_);
+ false, 1, false, use_image_texture_targets_);
child_resource_provider_ = ResourceProvider::Create(
child_output_surface_.get(), shared_bitmap_manager_.get(),
gpu_memory_buffer_manager_.get(), main_thread_task_runner_.get(), 0,
- false, 1, use_image_texture_targets_);
+ false, 1, false, use_image_texture_targets_);
}
ResourceProviderTest() : ResourceProviderTest(true) {}
@@ -1378,7 +1378,7 @@ TEST_P(ResourceProviderTest, TransferGLToSoftware) {
scoped_ptr<ResourceProvider> child_resource_provider(ResourceProvider::Create(
child_output_surface.get(), shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(), NULL, 0, false, 1,
+ gpu_memory_buffer_manager_.get(), NULL, 0, false, 1, false,
use_image_texture_targets_));
gfx::Size size(1, 1);
@@ -1863,7 +1863,7 @@ class ResourceProviderTestTextureFilters : public ResourceProviderTest {
scoped_ptr<ResourceProvider> child_resource_provider(
ResourceProvider::Create(child_output_surface.get(),
shared_bitmap_manager.get(), NULL, NULL, 0,
- false, 1, use_image_texture_targets_));
+ false, 1, false, use_image_texture_targets_));
scoped_ptr<TextureStateTrackingContext> parent_context_owned(
new TextureStateTrackingContext);
@@ -1877,7 +1877,7 @@ class ResourceProviderTestTextureFilters : public ResourceProviderTest {
scoped_ptr<ResourceProvider> parent_resource_provider(
ResourceProvider::Create(parent_output_surface.get(),
shared_bitmap_manager.get(), NULL, NULL, 0,
- false, 1, use_image_texture_targets_));
+ false, 1, false, use_image_texture_targets_));
gfx::Size size(1, 1);
ResourceFormat format = RGBA_8888;
@@ -2509,7 +2509,7 @@ TEST_P(ResourceProviderTest, ScopedSampler) {
scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
output_surface.get(), shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(), NULL, 0, false, 1,
+ gpu_memory_buffer_manager_.get(), NULL, 0, false, 1, false,
use_image_texture_targets_));
gfx::Size size(1, 1);
@@ -2592,7 +2592,7 @@ TEST_P(ResourceProviderTest, ManagedResource) {
scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
output_surface.get(), shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(), NULL, 0, false, 1,
+ gpu_memory_buffer_manager_.get(), NULL, 0, false, 1, false,
use_image_texture_targets_));
gfx::Size size(1, 1);
@@ -2640,7 +2640,7 @@ TEST_P(ResourceProviderTest, TextureWrapMode) {
scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
output_surface.get(), shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(), NULL, 0, false, 1,
+ gpu_memory_buffer_manager_.get(), NULL, 0, false, 1, false,
use_image_texture_targets_));
gfx::Size size(1, 1);
@@ -2691,7 +2691,7 @@ TEST_P(ResourceProviderTest, TextureHint) {
scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
output_surface.get(), shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(), NULL, 0, false, 1,
+ gpu_memory_buffer_manager_.get(), NULL, 0, false, 1, false,
use_image_texture_targets_));
gfx::Size size(1, 1);
@@ -2757,7 +2757,7 @@ TEST_P(ResourceProviderTest, TextureMailbox_SharedMemory) {
scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
output_surface.get(), shared_bitmap_manager_.get(),
gpu_memory_buffer_manager_.get(), main_thread_task_runner_.get(), 0,
- false, 1, use_image_texture_targets_));
+ false, 1, false, use_image_texture_targets_));
uint32 release_sync_point = 0;
bool lost_resource = false;
@@ -2806,7 +2806,8 @@ class ResourceProviderTestTextureMailboxGLFilters
scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
output_surface.get(), shared_bitmap_manager, gpu_memory_buffer_manager,
- main_thread_task_runner, 0, false, 1, use_image_texture_targets_));
+ main_thread_task_runner, 0, false, 1, false,
+ use_image_texture_targets_));
unsigned texture_id = 1;
uint32 sync_point = 30;
@@ -2949,7 +2950,7 @@ TEST_P(ResourceProviderTest, TextureMailbox_GLTextureExternalOES) {
scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
output_surface.get(), shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(), NULL, 0, false, 1,
+ gpu_memory_buffer_manager_.get(), NULL, 0, false, 1, false,
use_image_texture_targets_));
uint32 sync_point = 30;
@@ -3019,7 +3020,7 @@ TEST_P(ResourceProviderTest,
scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
output_surface.get(), shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(), NULL, 0, false, 1,
+ gpu_memory_buffer_manager_.get(), NULL, 0, false, 1, false,
use_image_texture_targets_));
uint32 sync_point = 30;
@@ -3073,7 +3074,7 @@ TEST_P(ResourceProviderTest, TextureMailbox_WaitSyncPointIfNeeded_NoSyncPoint) {
scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
output_surface.get(), shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(), NULL, 0, false, 1,
+ gpu_memory_buffer_manager_.get(), NULL, 0, false, 1, false,
use_image_texture_targets_));
uint32 sync_point = 0;
@@ -3194,7 +3195,7 @@ TEST_P(ResourceProviderTest, TextureAllocation) {
scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
output_surface.get(), shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(), NULL, 0, false, 1,
+ gpu_memory_buffer_manager_.get(), NULL, 0, false, 1, false,
use_image_texture_targets_));
gfx::Size size(2, 2);
@@ -3269,7 +3270,7 @@ TEST_P(ResourceProviderTest, TextureAllocationHint) {
scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
output_surface.get(), shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(), NULL, 0, false, 1,
+ gpu_memory_buffer_manager_.get(), NULL, 0, false, 1, false,
use_image_texture_targets_));
gfx::Size size(2, 2);
@@ -3325,7 +3326,7 @@ TEST_P(ResourceProviderTest, TextureAllocationHint_BGRA) {
scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
output_surface.get(), shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(), NULL, 0, false, 1,
+ gpu_memory_buffer_manager_.get(), NULL, 0, false, 1, false,
use_image_texture_targets_));
gfx::Size size(2, 2);
@@ -3380,7 +3381,7 @@ TEST_P(ResourceProviderTest, PixelBuffer_GLTexture) {
scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
output_surface.get(), shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(), NULL, 0, false, 1,
+ gpu_memory_buffer_manager_.get(), NULL, 0, false, 1, false,
use_image_texture_targets_));
id = resource_provider->CreateResource(
@@ -3423,7 +3424,7 @@ TEST_P(ResourceProviderTest, ForcingAsyncUploadToComplete) {
scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
output_surface.get(), shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(), NULL, 0, false, 1,
+ gpu_memory_buffer_manager_.get(), NULL, 0, false, 1, false,
use_image_texture_targets_));
id = resource_provider->CreateResource(
@@ -3466,7 +3467,7 @@ TEST_P(ResourceProviderTest, PixelBufferLostContext) {
scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
output_surface.get(), shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(), NULL, 0, false, 1,
+ gpu_memory_buffer_manager_.get(), NULL, 0, false, 1, false,
use_image_texture_targets_));
EXPECT_CALL(*context, NextTextureId()).WillRepeatedly(Return(texture_id));
@@ -3507,7 +3508,7 @@ TEST_P(ResourceProviderTest, Image_GLTexture) {
scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
output_surface.get(), shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(), NULL, 0, false, 1,
+ gpu_memory_buffer_manager_.get(), NULL, 0, false, 1, false,
use_image_texture_targets_));
id = resource_provider->CreateResource(
@@ -3568,6 +3569,89 @@ TEST_P(ResourceProviderTest, Image_GLTexture) {
.RetiresOnSaturation();
}
+TEST_P(ResourceProviderTest, CopyResource_GLTexture) {
+ if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
+ return;
+ scoped_ptr<AllocationTrackingContext3D> context_owned(
+ new StrictMock<AllocationTrackingContext3D>);
+ AllocationTrackingContext3D* context = context_owned.get();
+ context_owned->set_support_sync_query(true);
+
+ FakeOutputSurfaceClient output_surface_client;
+ scoped_ptr<OutputSurface> output_surface(
+ FakeOutputSurface::Create3d(context_owned.Pass()));
+ ASSERT_TRUE(output_surface->BindToClient(&output_surface_client));
+
+ const int kWidth = 2;
+ const int kHeight = 2;
+ gfx::Size size(kWidth, kHeight);
+ ResourceFormat format = RGBA_8888;
+ ResourceId source_id = 0;
+ ResourceId dest_id = 0;
+ const unsigned kSourceTextureId = 123u;
+ const unsigned kDestTextureId = 321u;
+ const unsigned kImageId = 234u;
+
+ scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
+ output_surface.get(), shared_bitmap_manager_.get(),
+ gpu_memory_buffer_manager_.get(), NULL, 0, false, 1, false,
+ std::vector<unsigned>(static_cast<size_t>(gfx::BufferFormat::LAST) + 1,
+ GL_TEXTURE_2D)));
+
+ source_id = resource_provider->CreateResource(
+ size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
+
+ EXPECT_CALL(*context, NextTextureId())
+ .WillOnce(Return(kSourceTextureId))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, kSourceTextureId))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*context, createImageCHROMIUM(_, kWidth, kHeight, GL_RGBA))
+ .WillOnce(Return(kImageId))
+ .RetiresOnSaturation();
+ {
+ ResourceProvider::ScopedWriteLockGpuMemoryBuffer lock(
+ resource_provider.get(), source_id);
+ EXPECT_TRUE(lock.GetGpuMemoryBuffer());
+ }
+ Mock::VerifyAndClearExpectations(context);
+
+ dest_id = resource_provider->CreateResource(
+ size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
+
+ EXPECT_CALL(*context, NextTextureId())
+ .WillOnce(Return(kDestTextureId))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, kDestTextureId))
+ .Times(2)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*context, texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA,
+ GL_UNSIGNED_BYTE, nullptr))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, kSourceTextureId))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*context, bindTexImage2DCHROMIUM(GL_TEXTURE_2D, kImageId))
+ .Times(1)
+ .RetiresOnSaturation();
+ resource_provider->CopyResource(source_id, dest_id, gfx::Rect(size));
+ Mock::VerifyAndClearExpectations(context);
+
+ EXPECT_CALL(*context, destroyImageCHROMIUM(kImageId))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*context, RetireTextureId(kSourceTextureId))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*context, RetireTextureId(kDestTextureId))
+ .Times(1)
+ .RetiresOnSaturation();
+ resource_provider->DeleteResource(source_id);
+ resource_provider->DeleteResource(dest_id);
+}
+
TEST_P(ResourceProviderTest, CompressedTextureETC1Allocate) {
if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
return;
@@ -3585,7 +3669,7 @@ TEST_P(ResourceProviderTest, CompressedTextureETC1Allocate) {
gfx::Size size(4, 4);
scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
output_surface.get(), shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(), NULL, 0, false, 1,
+ gpu_memory_buffer_manager_.get(), NULL, 0, false, 1, false,
use_image_texture_targets_));
int texture_id = 123;
@@ -3617,7 +3701,7 @@ TEST_P(ResourceProviderTest, CompressedTextureETC1Upload) {
gfx::Size size(4, 4);
scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
output_surface.get(), shared_bitmap_manager_.get(),
- gpu_memory_buffer_manager_.get(), NULL, 0, false, 1,
+ gpu_memory_buffer_manager_.get(), NULL, 0, false, 1, false,
use_image_texture_targets_));
int texture_id = 123;
uint8_t pixels[8];
@@ -3674,7 +3758,7 @@ TEST(ResourceProviderTest, TextureAllocationChunkSize) {
size_t kTextureAllocationChunkSize = 1;
scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
output_surface.get(), shared_bitmap_manager.get(), NULL, NULL, 0, false,
- kTextureAllocationChunkSize,
+ kTextureAllocationChunkSize, false,
ResourceProviderTest::use_image_texture_targets()));
ResourceId id = resource_provider->CreateResource(
@@ -3691,7 +3775,7 @@ TEST(ResourceProviderTest, TextureAllocationChunkSize) {
size_t kTextureAllocationChunkSize = 8;
scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
output_surface.get(), shared_bitmap_manager.get(), NULL, NULL, 0, false,
- kTextureAllocationChunkSize,
+ kTextureAllocationChunkSize, false,
ResourceProviderTest::use_image_texture_targets()));
ResourceId id = resource_provider->CreateResource(