Skip to content

Commit

Permalink
gpu: Add CHROMIUM_image support to in-process command buffer.
Browse files Browse the repository at this point in the history
This makes it possible to use the in-process command buffer
with CHROMIUM_image extension. GpuMemoryBufferManager and
ImageFactory interfaces need to be provided when creating
an in-process command buffer. Existing implementations
of these interfaces in content/ should work just fine.

cc::TestGpuMemoryBufferManager and cc::TestImageFactory
are used for cc pixel tests. They provide a minimal
implementation of these interfaces using shared memory.

Note: shared memory is used for in-process testing as it
maps better to the GpuMemoryBuffer framework that has
been designed for multi-process usage. Non-shared memory
might be a bit more efficient but it would require more
complexity and not match real usage as well.

BUG=423533

Review URL: https://codereview.chromium.org/665463003

Cr-Commit-Position: refs/heads/master@{#301763}
  • Loading branch information
reveman-chromium authored and Commit bot committed Oct 29, 2014
1 parent cb127d4 commit 2232bce
Show file tree
Hide file tree
Showing 16 changed files with 277 additions and 52 deletions.
4 changes: 3 additions & 1 deletion android_webview/browser/hardware_renderer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ scoped_refptr<cc::ContextProvider> CreateContext(
false /* share_resources */,
attribs_for_gles2,
gpu_preference,
gpu::GLInProcessContextSharedMemoryLimits()));
gpu::GLInProcessContextSharedMemoryLimits(),
nullptr,
nullptr));
DCHECK(context.get());

return webkit::gpu::ContextProviderInProcess::Create(
Expand Down
2 changes: 2 additions & 0 deletions cc/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,8 @@ source_set("test_support") {
"test/test_gles2_interface.h",
"test/test_gpu_memory_buffer_manager.cc",
"test/test_gpu_memory_buffer_manager.h",
"test/test_image_factory.cc",
"test/test_image_factory.h",
"test/test_now_source.cc",
"test/test_now_source.h",
"test/test_occlusion_tracker.h",
Expand Down
2 changes: 2 additions & 0 deletions cc/cc_tests.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,8 @@
'test/test_gles2_interface.h',
'test/test_gpu_memory_buffer_manager.cc',
'test/test_gpu_memory_buffer_manager.h',
'test/test_image_factory.cc',
'test/test_image_factory.h',
'test/test_now_source.cc',
'test/test_now_source.h',
'test/test_occlusion_tracker.h',
Expand Down
1 change: 1 addition & 0 deletions cc/test/DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ include_rules = [
"+gpu/command_buffer/client/gles2_interface_stub.h",
"+gpu/command_buffer/client/gles2_lib.h",
"+gpu/command_buffer/common/gles2_cmd_utils.h",
"+gpu/command_buffer/service/image_factory.h",
"+gpu/skia_bindings/gl_bindings_skia_cmd_buffer.h",
]
48 changes: 29 additions & 19 deletions cc/test/test_gpu_memory_buffer_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,39 @@
namespace cc {
namespace {

size_t BytesPerPixel(gfx::GpuMemoryBuffer::Format format) {
switch (format) {
case gfx::GpuMemoryBuffer::RGBA_8888:
case gfx::GpuMemoryBuffer::RGBX_8888:
case gfx::GpuMemoryBuffer::BGRA_8888:
return 4;
}

NOTREACHED();
return 0;
}

class GpuMemoryBufferImpl : public gfx::GpuMemoryBuffer {
public:
GpuMemoryBufferImpl(const gfx::Size& size, Format format)
GpuMemoryBufferImpl(const gfx::Size& size,
Format format,
scoped_ptr<base::SharedMemory> shared_memory)
: size_(size),
format_(format),
pixels_(new uint8[size.GetArea() * BytesPerPixel(format)]),
shared_memory_(shared_memory.Pass()),
mapped_(false) {}

// Overridden from gfx::GpuMemoryBuffer:
void* Map() override {
DCHECK(!mapped_);
if (!shared_memory_->Map(size_.GetArea() * BytesPerPixel(format_)))
return NULL;
mapped_ = true;
return pixels_.get();
return shared_memory_->memory();
}
void Unmap() override {
DCHECK(mapped_);
shared_memory_->Unmap();
mapped_ = false;
}
bool IsMapped() const override { return mapped_; }
Expand All @@ -34,29 +51,19 @@ class GpuMemoryBufferImpl : public gfx::GpuMemoryBuffer {
return size_.width() * BytesPerPixel(format_);
}
gfx::GpuMemoryBufferHandle GetHandle() const override {
NOTREACHED();
return gfx::GpuMemoryBufferHandle();
gfx::GpuMemoryBufferHandle handle;
handle.type = gfx::SHARED_MEMORY_BUFFER;
handle.handle = shared_memory_->handle();
return handle;
}
ClientBuffer AsClientBuffer() override {
return reinterpret_cast<ClientBuffer>(this);
}

private:
static size_t BytesPerPixel(Format format) {
switch (format) {
case RGBA_8888:
case RGBX_8888:
case BGRA_8888:
return 4;
}

NOTREACHED();
return 0;
}

const gfx::Size size_;
gfx::GpuMemoryBuffer::Format format_;
scoped_ptr<uint8[]> pixels_;
scoped_ptr<base::SharedMemory> shared_memory_;
bool mapped_;
};

Expand All @@ -73,8 +80,11 @@ TestGpuMemoryBufferManager::AllocateGpuMemoryBuffer(
const gfx::Size& size,
gfx::GpuMemoryBuffer::Format format,
gfx::GpuMemoryBuffer::Usage usage) {
scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory);
if (!shared_memory->CreateAnonymous(size.GetArea() * BytesPerPixel(format)))
return nullptr;
return make_scoped_ptr<gfx::GpuMemoryBuffer>(
new GpuMemoryBufferImpl(size, format));
new GpuMemoryBufferImpl(size, format, shared_memory.Pass()));
}

gfx::GpuMemoryBuffer*
Expand Down
3 changes: 3 additions & 0 deletions cc/test/test_gpu_memory_buffer_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ class TestGpuMemoryBufferManager : public gpu::GpuMemoryBufferManager {
gfx::GpuMemoryBuffer::Usage usage) override;
gfx::GpuMemoryBuffer* GpuMemoryBufferFromClientBuffer(
ClientBuffer buffer) override;

private:
DISALLOW_COPY_AND_ASSIGN(TestGpuMemoryBufferManager);
};

} // namespace cc
Expand Down
33 changes: 33 additions & 0 deletions cc/test/test_image_factory.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "cc/test/test_image_factory.h"

#include "ui/gl/gl_image_shared_memory.h"

namespace cc {

TestImageFactory::TestImageFactory() {
}

TestImageFactory::~TestImageFactory() {
}

scoped_refptr<gfx::GLImage> TestImageFactory::CreateImageForGpuMemoryBuffer(
const gfx::GpuMemoryBufferHandle& handle,
const gfx::Size& size,
gfx::GpuMemoryBuffer::Format format,
unsigned internalformat,
int client_id) {
DCHECK_EQ(handle.type, gfx::SHARED_MEMORY_BUFFER);

scoped_refptr<gfx::GLImageSharedMemory> image(
new gfx::GLImageSharedMemory(size, internalformat));
if (!image->Initialize(handle, format))
return nullptr;

return image;
}

} // namespace cc
31 changes: 31 additions & 0 deletions cc/test/test_image_factory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CC_TEST_TEST_IMAGE_FACTORY_H_
#define CC_TEST_TEST_IMAGE_FACTORY_H_

#include "gpu/command_buffer/service/image_factory.h"

namespace cc {

class TestImageFactory : public gpu::ImageFactory {
public:
TestImageFactory();
~TestImageFactory() override;

// Overridden from gpu::ImageFactory:
scoped_refptr<gfx::GLImage> CreateImageForGpuMemoryBuffer(
const gfx::GpuMemoryBufferHandle& handle,
const gfx::Size& size,
gfx::GpuMemoryBuffer::Format format,
unsigned internalformat,
int client_id) override;

private:
DISALLOW_COPY_AND_ASSIGN(TestImageFactory);
};

} // namespace cc

#endif // CC_TEST_TEST_IMAGE_FACTORY_H_
16 changes: 13 additions & 3 deletions cc/test/test_in_process_context_provider.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
namespace cc {

// static
scoped_ptr<gpu::GLInProcessContext> CreateTestInProcessContext() {
scoped_ptr<gpu::GLInProcessContext> CreateTestInProcessContext(
TestGpuMemoryBufferManager* gpu_memory_buffer_manager,
TestImageFactory* image_factory) {
const bool is_offscreen = true;
const bool share_resources = true;
gpu::gles2::ContextCreationAttribHelper attribs;
Expand All @@ -47,14 +49,22 @@ scoped_ptr<gpu::GLInProcessContext> CreateTestInProcessContext() {
share_resources,
attribs,
gpu_preference,
gpu::GLInProcessContextSharedMemoryLimits()));
gpu::GLInProcessContextSharedMemoryLimits(),
gpu_memory_buffer_manager,
image_factory));

DCHECK(context);
return context.Pass();
}

scoped_ptr<gpu::GLInProcessContext> CreateTestInProcessContext() {
return CreateTestInProcessContext(nullptr, nullptr);
}

TestInProcessContextProvider::TestInProcessContextProvider()
: context_(CreateTestInProcessContext()) {}
: context_(CreateTestInProcessContext(&gpu_memory_buffer_manager_,
&image_factory_)) {
}

TestInProcessContextProvider::~TestInProcessContextProvider() {
}
Expand Down
7 changes: 7 additions & 0 deletions cc/test/test_in_process_context_provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#define CC_TEST_TEST_IN_PROCESS_CONTEXT_PROVIDER_H_

#include "cc/output/context_provider.h"
#include "cc/test/test_gpu_memory_buffer_manager.h"
#include "cc/test/test_image_factory.h"
#include "skia/ext/refptr.h"

class GrContext;
Expand All @@ -17,6 +19,9 @@ class GLInProcessContext;
namespace cc {

scoped_ptr<gpu::GLInProcessContext> CreateTestInProcessContext();
scoped_ptr<gpu::GLInProcessContext> CreateTestInProcessContext(
TestGpuMemoryBufferManager* gpu_memory_buffer_manager,
TestImageFactory* image_factory);

class TestInProcessContextProvider : public ContextProvider {
public:
Expand All @@ -42,6 +47,8 @@ class TestInProcessContextProvider : public ContextProvider {
~TestInProcessContextProvider() override;

private:
TestGpuMemoryBufferManager gpu_memory_buffer_manager_;
TestImageFactory image_factory_;
scoped_ptr<gpu::GLInProcessContext> context_;
skia::RefPtr<class GrContext> gr_context_;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ scoped_ptr<gpu::GLInProcessContext> CreateOffscreenContext(
false /* share_resources */,
in_process_attribs,
gpu_preference,
gpu::GLInProcessContextSharedMemoryLimits()));
gpu::GLInProcessContextSharedMemoryLimits(),
nullptr,
nullptr));
return context.Pass();
}

Expand All @@ -78,7 +80,9 @@ scoped_ptr<gpu::GLInProcessContext> CreateContext(
false /* share_resources */,
in_process_attribs,
gpu_preference,
mem_limits));
mem_limits,
nullptr,
nullptr));
return context.Pass();
}

Expand Down
37 changes: 23 additions & 14 deletions gpu/command_buffer/client/gl_in_process_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,17 @@ class GLInProcessContextImpl
const GLInProcessContextSharedMemoryLimits& mem_limits);
~GLInProcessContextImpl() override;

bool Initialize(
scoped_refptr<gfx::GLSurface> surface,
bool is_offscreen,
bool use_global_share_group,
GLInProcessContext* share_context,
gfx::AcceleratedWidget window,
const gfx::Size& size,
const gpu::gles2::ContextCreationAttribHelper& attribs,
gfx::GpuPreference gpu_preference,
const scoped_refptr<InProcessCommandBuffer::Service>& service);
bool Initialize(scoped_refptr<gfx::GLSurface> surface,
bool is_offscreen,
bool use_global_share_group,
GLInProcessContext* share_context,
gfx::AcceleratedWidget window,
const gfx::Size& size,
const gpu::gles2::ContextCreationAttribHelper& attribs,
gfx::GpuPreference gpu_preference,
const scoped_refptr<InProcessCommandBuffer::Service>& service,
GpuMemoryBufferManager* gpu_memory_buffer_manager,
ImageFactory* image_factory);

// GLInProcessContext implementation:
void SetContextLostCallback(const base::Closure& callback) override;
Expand Down Expand Up @@ -135,7 +136,9 @@ bool GLInProcessContextImpl::Initialize(
const gfx::Size& size,
const gles2::ContextCreationAttribHelper& attribs,
gfx::GpuPreference gpu_preference,
const scoped_refptr<InProcessCommandBuffer::Service>& service) {
const scoped_refptr<InProcessCommandBuffer::Service>& service,
GpuMemoryBufferManager* gpu_memory_buffer_manager,
ImageFactory* image_factory) {
DCHECK(!use_global_share_group || !share_context);
DCHECK(size.width() >= 0 && size.height() >= 0);

Expand Down Expand Up @@ -181,7 +184,9 @@ bool GLInProcessContextImpl::Initialize(
attrib_vector,
gpu_preference,
wrapped_callback,
share_command_buffer)) {
share_command_buffer,
gpu_memory_buffer_manager,
image_factory)) {
LOG(ERROR) << "Failed to initialize InProcessCommmandBuffer";
return false;
}
Expand Down Expand Up @@ -271,7 +276,9 @@ GLInProcessContext* GLInProcessContext::Create(
bool use_global_share_group,
const ::gpu::gles2::ContextCreationAttribHelper& attribs,
gfx::GpuPreference gpu_preference,
const GLInProcessContextSharedMemoryLimits& memory_limits) {
const GLInProcessContextSharedMemoryLimits& memory_limits,
GpuMemoryBufferManager* gpu_memory_buffer_manager,
ImageFactory* image_factory) {
DCHECK(!use_global_share_group || !share_context);
if (surface.get()) {
DCHECK_EQ(surface->IsOffscreen(), is_offscreen);
Expand All @@ -289,7 +296,9 @@ GLInProcessContext* GLInProcessContext::Create(
size,
attribs,
gpu_preference,
service))
service,
gpu_memory_buffer_manager,
image_factory))
return NULL;

return context.release();
Expand Down
4 changes: 3 additions & 1 deletion gpu/command_buffer/client/gl_in_process_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ class GL_IN_PROCESS_CONTEXT_EXPORT GLInProcessContext {
bool use_global_share_group,
const gpu::gles2::ContextCreationAttribHelper& attribs,
gfx::GpuPreference gpu_preference,
const GLInProcessContextSharedMemoryLimits& memory_limits);
const GLInProcessContextSharedMemoryLimits& memory_limits,
GpuMemoryBufferManager* gpu_memory_buffer_manager,
ImageFactory* image_factory);

virtual void SetContextLostCallback(const base::Closure& callback) = 0;

Expand Down
Loading

0 comments on commit 2232bce

Please sign in to comment.