blob: f6080506caadab0bfbdbb6aba88c7ee5a1289ec9 [file] [log] [blame]
// 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 "content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.h"
#include "base/debug/trace_event.h"
#include "base/logging.h"
#include "content/common/android/surface_texture_lookup.h"
#include "ui/gl/gl_bindings.h"
namespace content {
GpuMemoryBufferImplSurfaceTexture::GpuMemoryBufferImplSurfaceTexture(
const gfx::Size& size,
unsigned internalformat)
: GpuMemoryBufferImpl(size, internalformat),
native_window_(NULL),
stride_(0u) {}
GpuMemoryBufferImplSurfaceTexture::~GpuMemoryBufferImplSurfaceTexture() {
if (native_window_)
ANativeWindow_release(native_window_);
}
// static
bool GpuMemoryBufferImplSurfaceTexture::IsFormatSupported(
unsigned internalformat) {
switch (internalformat) {
case GL_RGBA8_OES:
return true;
default:
return false;
}
}
// static
bool GpuMemoryBufferImplSurfaceTexture::IsUsageSupported(unsigned usage) {
switch (usage) {
case GL_IMAGE_MAP_CHROMIUM:
return true;
default:
return false;
}
}
// static
bool GpuMemoryBufferImplSurfaceTexture::IsConfigurationSupported(
unsigned internalformat,
unsigned usage) {
return IsFormatSupported(internalformat) && IsUsageSupported(usage);
}
// static
int GpuMemoryBufferImplSurfaceTexture::WindowFormat(unsigned internalformat) {
switch (internalformat) {
case GL_RGBA8_OES:
return WINDOW_FORMAT_RGBA_8888;
default:
NOTREACHED();
return 0;
}
}
bool GpuMemoryBufferImplSurfaceTexture::InitializeFromHandle(
gfx::GpuMemoryBufferHandle handle) {
TRACE_EVENT0("gpu",
"GpuMemoryBufferImplSurfaceTexture::InitializeFromHandle");
DCHECK(IsFormatSupported(internalformat_));
DCHECK(!native_window_);
native_window_ = SurfaceTextureLookup::GetInstance()->AcquireNativeWidget(
handle.surface_texture_id.primary_id,
handle.surface_texture_id.secondary_id);
if (!native_window_)
return false;
ANativeWindow_setBuffersGeometry(native_window_,
size_.width(),
size_.height(),
WindowFormat(internalformat_));
surface_texture_id_ = handle.surface_texture_id;
return true;
}
void* GpuMemoryBufferImplSurfaceTexture::Map() {
TRACE_EVENT0("gpu", "GpuMemoryBufferImplSurfaceTexture::Map");
DCHECK(!mapped_);
DCHECK(native_window_);
ANativeWindow_Buffer buffer;
int status = ANativeWindow_lock(native_window_, &buffer, NULL);
if (status) {
VLOG(1) << "ANativeWindow_lock failed with error code: " << status;
return NULL;
}
DCHECK_LE(size_.width(), buffer.stride);
stride_ = buffer.stride * BytesPerPixel(internalformat_);
mapped_ = true;
return buffer.bits;
}
void GpuMemoryBufferImplSurfaceTexture::Unmap() {
TRACE_EVENT0("gpu", "GpuMemoryBufferImplSurfaceTexture::Unmap");
DCHECK(mapped_);
ANativeWindow_unlockAndPost(native_window_);
mapped_ = false;
}
uint32 GpuMemoryBufferImplSurfaceTexture::GetStride() const { return stride_; }
gfx::GpuMemoryBufferHandle GpuMemoryBufferImplSurfaceTexture::GetHandle()
const {
gfx::GpuMemoryBufferHandle handle;
handle.type = gfx::SURFACE_TEXTURE_BUFFER;
handle.surface_texture_id = surface_texture_id_;
return handle;
}
} // namespace content