blob: 63771c682574c2bd8e39f2343e2aad74cf3e3d00 [file] [log] [blame]
// Copyright 2013 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 "android_webview/browser/gpu_memory_buffer_factory_impl.h"
#include "android_webview/public/browser/draw_gl.h"
#include "base/logging.h"
#include "gpu/command_buffer/service/in_process_command_buffer.h"
#include "ui/gfx/gpu_memory_buffer.h"
#include "ui/gfx/size.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_image_android_native_buffer.h"
namespace android_webview {
namespace {
// Provides hardware rendering functions from the Android glue layer.
AwDrawGLFunctionTable* g_gl_draw_functions = NULL;
class GpuMemoryBufferImpl : public gfx::GpuMemoryBuffer {
public:
GpuMemoryBufferImpl(long buffer_id, const gfx::Size& size)
: buffer_id_(buffer_id), size_(size), mapped_(false) {
DCHECK(buffer_id_);
}
virtual ~GpuMemoryBufferImpl() {
g_gl_draw_functions->release_graphic_buffer(buffer_id_);
}
// Overridden from gfx::GpuMemoryBuffer:
virtual void* Map() OVERRIDE {
void* vaddr = NULL;
int err = g_gl_draw_functions->map(buffer_id_, MAP_READ_WRITE, &vaddr);
DCHECK(!err);
mapped_ = true;
return vaddr;
}
virtual void Unmap() OVERRIDE {
int err = g_gl_draw_functions->unmap(buffer_id_);
DCHECK(!err);
mapped_ = false;
}
virtual bool IsMapped() const OVERRIDE { return mapped_; }
virtual uint32 GetStride() const OVERRIDE {
return g_gl_draw_functions->get_stride(buffer_id_);
}
virtual gfx::GpuMemoryBufferHandle GetHandle() const OVERRIDE {
gfx::GpuMemoryBufferHandle handle;
handle.type = gfx::ANDROID_NATIVE_BUFFER;
handle.buffer_id = buffer_id_;
return handle;
}
private:
long buffer_id_;
gfx::Size size_;
bool mapped_;
DISALLOW_COPY_AND_ASSIGN(GpuMemoryBufferImpl);
};
} // namespace
GpuMemoryBufferFactoryImpl::GpuMemoryBufferFactoryImpl() {
}
GpuMemoryBufferFactoryImpl::~GpuMemoryBufferFactoryImpl() {
}
scoped_ptr<gfx::GpuMemoryBuffer>
GpuMemoryBufferFactoryImpl::AllocateGpuMemoryBuffer(size_t width,
size_t height,
unsigned internalformat,
unsigned usage) {
// For Android WebView we assume the |internalformat| will always be
// GL_RGBA8_OES.
CHECK_EQ(static_cast<GLenum>(GL_RGBA8_OES), internalformat);
CHECK(g_gl_draw_functions);
long buffer_id = g_gl_draw_functions->create_graphic_buffer(width, height);
if (!buffer_id)
return scoped_ptr<gfx::GpuMemoryBuffer>();
return make_scoped_ptr(
new GpuMemoryBufferImpl(buffer_id, gfx::Size(width, height)))
.PassAs<gfx::GpuMemoryBuffer>();
}
scoped_refptr<gfx::GLImage>
GpuMemoryBufferFactoryImpl::CreateImageForGpuMemoryBuffer(
const gfx::GpuMemoryBufferHandle& handle,
const gfx::Size& size,
unsigned internalformat) {
DCHECK_EQ(gfx::ANDROID_NATIVE_BUFFER, handle.type);
EGLClientBuffer native_buffer =
g_gl_draw_functions->get_native_buffer(handle.buffer_id);
DCHECK(native_buffer);
scoped_refptr<gfx::GLImageAndroidNativeBuffer> image(
new gfx::GLImageAndroidNativeBuffer(size));
if (!image->Initialize(native_buffer))
return scoped_refptr<gfx::GLImage>();
return image;
}
// static
void GpuMemoryBufferFactoryImpl::SetAwDrawGLFunctionTable(
AwDrawGLFunctionTable* table) {
g_gl_draw_functions = table;
}
bool GpuMemoryBufferFactoryImpl::Initialize() {
if (!g_gl_draw_functions)
return false;
gpu::InProcessCommandBuffer::SetGpuMemoryBufferFactory(this);
return true;
}
} // namespace android_webview