blob: b1611b38e2ac90f42a95519eb77c00e457451284 [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/logging.h"
#include "base/trace_event/trace_event.h"
#include "content/common/android/surface_texture_manager.h"
#include "ui/gl/gl_bindings.h"
namespace content {
namespace {
int WindowFormat(gfx::GpuMemoryBuffer::Format format) {
switch (format) {
case gfx::GpuMemoryBuffer::RGBA_8888:
return WINDOW_FORMAT_RGBA_8888;
case gfx::GpuMemoryBuffer::ATC:
case gfx::GpuMemoryBuffer::ATCIA:
case gfx::GpuMemoryBuffer::DXT1:
case gfx::GpuMemoryBuffer::DXT5:
case gfx::GpuMemoryBuffer::ETC1:
case gfx::GpuMemoryBuffer::R_8:
case gfx::GpuMemoryBuffer::RGBX_8888:
case gfx::GpuMemoryBuffer::BGRA_8888:
case gfx::GpuMemoryBuffer::YUV_420:
NOTREACHED();
return 0;
}
NOTREACHED();
return 0;
}
} // namespace
GpuMemoryBufferImplSurfaceTexture::GpuMemoryBufferImplSurfaceTexture(
gfx::GpuMemoryBufferId id,
const gfx::Size& size,
Format format,
const DestructionCallback& callback,
ANativeWindow* native_window)
: GpuMemoryBufferImpl(id, size, format, callback),
native_window_(native_window),
stride_(0) {
}
GpuMemoryBufferImplSurfaceTexture::~GpuMemoryBufferImplSurfaceTexture() {
ANativeWindow_release(native_window_);
}
// static
scoped_ptr<GpuMemoryBufferImpl>
GpuMemoryBufferImplSurfaceTexture::CreateFromHandle(
const gfx::GpuMemoryBufferHandle& handle,
const gfx::Size& size,
Format format,
const DestructionCallback& callback) {
ANativeWindow* native_window = SurfaceTextureManager::GetInstance()->
AcquireNativeWidgetForSurfaceTexture(handle.id);
if (!native_window)
return scoped_ptr<GpuMemoryBufferImpl>();
ANativeWindow_setBuffersGeometry(
native_window, size.width(), size.height(), WindowFormat(format));
return make_scoped_ptr<GpuMemoryBufferImpl>(
new GpuMemoryBufferImplSurfaceTexture(
handle.id, size, format, callback, native_window));
}
bool GpuMemoryBufferImplSurfaceTexture::Map(void** data) {
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 false;
}
DCHECK_LE(size_.width(), buffer.stride);
size_t row_size_in_bytes = 0;
bool valid_row_size =
RowSizeInBytes(buffer.stride, format_, 0, &row_size_in_bytes);
DCHECK(valid_row_size);
stride_ = row_size_in_bytes;
mapped_ = true;
*data = buffer.bits;
return true;
}
void GpuMemoryBufferImplSurfaceTexture::Unmap() {
TRACE_EVENT0("gpu", "GpuMemoryBufferImplSurfaceTexture::Unmap");
DCHECK(mapped_);
ANativeWindow_unlockAndPost(native_window_);
mapped_ = false;
}
void GpuMemoryBufferImplSurfaceTexture::GetStride(int* stride) const {
*stride = stride_;
}
gfx::GpuMemoryBufferHandle GpuMemoryBufferImplSurfaceTexture::GetHandle()
const {
gfx::GpuMemoryBufferHandle handle;
handle.type = gfx::SURFACE_TEXTURE_BUFFER;
handle.id = id_;
return handle;
}
} // namespace content