#include "gpu/command_buffer/tests/gl_manager.h"
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <GLES2/gl2extchromium.h>
+
#include <vector>
#include "base/at_exit.h"
#include "base/bind.h"
+#include "base/memory/ref_counted_memory.h"
#include "gpu/command_buffer/client/gles2_implementation.h"
#include "gpu/command_buffer/client/gles2_lib.h"
#include "gpu/command_buffer/client/transfer_buffer.h"
#include "gpu/command_buffer/service/context_group.h"
#include "gpu/command_buffer/service/gl_context_virtual.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
-#include "gpu/command_buffer/service/gpu_control_service.h"
#include "gpu/command_buffer/service/gpu_scheduler.h"
#include "gpu/command_buffer/service/image_manager.h"
-#include "gpu/command_buffer/service/mailbox_manager.h"
+#include "gpu/command_buffer/service/mailbox_manager_impl.h"
+#include "gpu/command_buffer/service/memory_tracking.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/gpu_memory_buffer.h"
#include "ui/gl/gl_context.h"
+#include "ui/gl/gl_image_ref_counted_memory.h"
#include "ui/gl/gl_share_group.h"
#include "ui/gl/gl_surface.h"
namespace gpu {
+namespace {
+
+size_t BytesPerPixel(gfx::GpuMemoryBuffer::Format format) {
+ switch (format) {
+ case gfx::GpuMemoryBuffer::RGBA_8888:
+ case gfx::GpuMemoryBuffer::BGRA_8888:
+ return 4;
+ case gfx::GpuMemoryBuffer::RGBX_8888:
+ NOTREACHED();
+ return 0;
+ }
+
+ NOTREACHED();
+ return 0;
+}
+
+class GpuMemoryBufferImpl : public gfx::GpuMemoryBuffer {
+ public:
+ GpuMemoryBufferImpl(base::RefCountedBytes* bytes,
+ const gfx::Size& size,
+ gfx::GpuMemoryBuffer::Format format)
+ : bytes_(bytes), size_(size), format_(format), mapped_(false) {}
+
+ static GpuMemoryBufferImpl* FromClientBuffer(ClientBuffer buffer) {
+ return reinterpret_cast<GpuMemoryBufferImpl*>(buffer);
+ }
+
+ // Overridden from gfx::GpuMemoryBuffer:
+ void* Map() override {
+ mapped_ = true;
+ return &bytes_->data().front();
+ }
+ void Unmap() override { mapped_ = false; }
+ bool IsMapped() const override { return mapped_; }
+ Format GetFormat() const override { return format_; }
+ uint32 GetStride() const override {
+ return size_.width() * BytesPerPixel(format_);
+ }
+ gfx::GpuMemoryBufferHandle GetHandle() const override {
+ NOTREACHED();
+ return gfx::GpuMemoryBufferHandle();
+ }
+ ClientBuffer AsClientBuffer() override {
+ return reinterpret_cast<ClientBuffer>(this);
+ }
+
+ base::RefCountedBytes* bytes() { return bytes_.get(); }
+
+ private:
+ scoped_refptr<base::RefCountedBytes> bytes_;
+ const gfx::Size size_;
+ gfx::GpuMemoryBuffer::Format format_;
+ bool mapped_;
+};
+
+} // namespace
int GLManager::use_count_;
scoped_refptr<gfx::GLShareGroup>* GLManager::base_share_group_;
share_mailbox_manager(NULL),
virtual_manager(NULL),
bind_generates_resource(false),
- context_lost_allowed(false),
- image_manager(NULL) {
+ lose_context_when_out_of_memory(false),
+ context_lost_allowed(false) {
}
-GLManager::GLManager()
- : context_lost_allowed_(false) {
+GLManager::GLManager() : context_lost_allowed_(false) {
SetupBaseContext();
}
}
}
+// static
+scoped_ptr<gfx::GpuMemoryBuffer> GLManager::CreateGpuMemoryBuffer(
+ const gfx::Size& size,
+ gfx::GpuMemoryBuffer::Format format) {
+ std::vector<unsigned char> data(size.GetArea() * BytesPerPixel(format), 0);
+ scoped_refptr<base::RefCountedBytes> bytes(new base::RefCountedBytes(data));
+ return make_scoped_ptr<gfx::GpuMemoryBuffer>(
+ new GpuMemoryBufferImpl(bytes.get(), size, format));
+}
+
void GLManager::Initialize(const GLManager::Options& options) {
const int32 kCommandBufferSize = 1024 * 1024;
const size_t kStartTransferBufferSize = 4 * 1024 * 1024;
}
mailbox_manager_ =
- mailbox_manager ? mailbox_manager : new gles2::MailboxManager;
+ mailbox_manager ? mailbox_manager : new gles2::MailboxManagerImpl;
share_group_ =
share_group ? share_group : new gfx::GLShareGroup;
gfx::GpuPreference gpu_preference(gfx::PreferDiscreteGpu);
std::vector<int32> attribs;
gles2::ContextCreationAttribHelper attrib_helper;
- attrib_helper.red_size_ = 8;
- attrib_helper.green_size_ = 8;
- attrib_helper.blue_size_ = 8;
- attrib_helper.alpha_size_ = 8;
- attrib_helper.depth_size_ = 16;
+ attrib_helper.red_size = 8;
+ attrib_helper.green_size = 8;
+ attrib_helper.blue_size = 8;
+ attrib_helper.alpha_size = 8;
+ attrib_helper.depth_size = 16;
attrib_helper.Serialize(&attribs);
if (!context_group) {
- context_group = new gles2::ContextGroup(mailbox_manager_.get(),
- options.image_manager,
- NULL,
- NULL,
- options.bind_generates_resource);
+ context_group =
+ new gles2::ContextGroup(mailbox_manager_.get(),
+ NULL,
+ new gpu::gles2::ShaderTranslatorCache,
+ NULL,
+ options.bind_generates_resource);
}
decoder_.reset(::gpu::gles2::GLES2Decoder::Create(context_group));
surface_ = gfx::GLSurface::CreateOffscreenGLSurface(options.size);
ASSERT_TRUE(surface_.get() != NULL) << "could not create offscreen surface";
- if (real_gl_context) {
+ if (base_context_) {
context_ = scoped_refptr<gfx::GLContext>(new gpu::GLContextVirtual(
- share_group_.get(), real_gl_context, decoder_->AsWeakPtr()));
+ share_group_.get(), base_context_->get(), decoder_->AsWeakPtr()));
ASSERT_TRUE(context_->Initialize(
surface_.get(), gfx::PreferIntegratedGpu));
} else {
- if (base_context_) {
+ if (real_gl_context) {
context_ = scoped_refptr<gfx::GLContext>(new gpu::GLContextVirtual(
- share_group_.get(), base_context_->get(), decoder_->AsWeakPtr()));
+ share_group_.get(), real_gl_context, decoder_->AsWeakPtr()));
ASSERT_TRUE(context_->Initialize(
surface_.get(), gfx::PreferIntegratedGpu));
} else {
::gpu::gles2::DisallowedFeatures(),
attribs)) << "could not initialize decoder";
- gpu_control_.reset(
- new GpuControlService(decoder_->GetContextGroup()->image_manager(),
- options.gpu_memory_buffer_factory,
- decoder_->GetContextGroup()->mailbox_manager(),
- decoder_->GetQueryManager()));
-
command_buffer_->SetPutOffsetChangeCallback(
base::Bind(&GLManager::PumpCommands, base::Unretained(this)));
command_buffer_->SetGetBufferChangeCallback(
transfer_buffer_.reset(new TransferBuffer(gles2_helper_.get()));
// Create the object exposing the OpenGL API.
- gles2_implementation_.reset(new gles2::GLES2Implementation(
- gles2_helper_.get(),
- client_share_group,
- transfer_buffer_.get(),
- options.bind_generates_resource,
- gpu_control_.get()));
+ const bool support_client_side_arrays = true;
+ gles2_implementation_.reset(
+ new gles2::GLES2Implementation(gles2_helper_.get(),
+ client_share_group,
+ transfer_buffer_.get(),
+ options.bind_generates_resource,
+ options.lose_context_when_out_of_memory,
+ support_client_side_arrays,
+ this));
ASSERT_TRUE(gles2_implementation_->Initialize(
kStartTransferBufferSize,
void GLManager::PumpCommands() {
decoder_->MakeCurrent();
gpu_scheduler_->PutChanged();
- ::gpu::CommandBuffer::State state = command_buffer_->GetState();
+ ::gpu::CommandBuffer::State state = command_buffer_->GetLastState();
if (!context_lost_allowed_) {
ASSERT_EQ(::gpu::error::kNoError, state.error);
}
return gpu_scheduler_->SetGetBuffer(transfer_buffer_id);
}
+Capabilities GLManager::GetCapabilities() {
+ return decoder_->GetCapabilities();
+}
+
+int32 GLManager::CreateImage(ClientBuffer buffer,
+ size_t width,
+ size_t height,
+ unsigned internalformat) {
+ GpuMemoryBufferImpl* gpu_memory_buffer =
+ GpuMemoryBufferImpl::FromClientBuffer(buffer);
+
+ scoped_refptr<gfx::GLImageRefCountedMemory> image(
+ new gfx::GLImageRefCountedMemory(gfx::Size(width, height),
+ internalformat));
+ if (!image->Initialize(gpu_memory_buffer->bytes(),
+ gpu_memory_buffer->GetFormat())) {
+ return -1;
+ }
+
+ static int32 next_id = 1;
+ int32 new_id = next_id++;
+
+ gpu::gles2::ImageManager* image_manager = decoder_->GetImageManager();
+ DCHECK(image_manager);
+ image_manager->AddImage(image.get(), new_id);
+ return new_id;
+}
+
+int32 GLManager::CreateGpuMemoryBufferImage(size_t width,
+ size_t height,
+ unsigned internalformat,
+ unsigned usage) {
+ DCHECK_EQ(usage, static_cast<unsigned>(GL_MAP_CHROMIUM));
+ scoped_ptr<gfx::GpuMemoryBuffer> buffer = GLManager::CreateGpuMemoryBuffer(
+ gfx::Size(width, height), gfx::GpuMemoryBuffer::RGBA_8888);
+ return CreateImage(buffer->AsClientBuffer(), width, height, internalformat);
+}
+
+void GLManager::DestroyImage(int32 id) {
+ gpu::gles2::ImageManager* image_manager = decoder_->GetImageManager();
+ DCHECK(image_manager);
+ image_manager->RemoveImage(id);
+}
+
+uint32 GLManager::InsertSyncPoint() {
+ NOTIMPLEMENTED();
+ return 0u;
+}
+
+uint32 GLManager::InsertFutureSyncPoint() {
+ NOTIMPLEMENTED();
+ return 0u;
+}
+
+void GLManager::RetireSyncPoint(uint32 sync_point) {
+ NOTIMPLEMENTED();
+}
+
+void GLManager::SignalSyncPoint(uint32 sync_point,
+ const base::Closure& callback) {
+ NOTIMPLEMENTED();
+}
+
+void GLManager::SignalQuery(uint32 query, const base::Closure& callback) {
+ NOTIMPLEMENTED();
+}
+
+void GLManager::SetSurfaceVisible(bool visible) {
+ NOTIMPLEMENTED();
+}
+
+uint32 GLManager::CreateStreamTexture(uint32 texture_id) {
+ NOTIMPLEMENTED();
+ return 0;
+}
+
} // namespace gpu