1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.h" 6 7#include "base/debug/trace_event.h" 8#include "base/logging.h" 9#include "content/common/android/surface_texture_lookup.h" 10#include "ui/gl/gl_bindings.h" 11 12namespace content { 13 14GpuMemoryBufferImplSurfaceTexture::GpuMemoryBufferImplSurfaceTexture( 15 const gfx::Size& size, 16 unsigned internalformat, 17 const DestructionCallback& callback, 18 const gfx::SurfaceTextureId& surface_texture_id, 19 ANativeWindow* native_window) 20 : GpuMemoryBufferImpl(size, internalformat, callback), 21 surface_texture_id_(surface_texture_id), 22 native_window_(native_window), 23 stride_(0u) { 24} 25 26GpuMemoryBufferImplSurfaceTexture::~GpuMemoryBufferImplSurfaceTexture() { 27 ANativeWindow_release(native_window_); 28} 29 30// static 31scoped_ptr<GpuMemoryBufferImpl> 32GpuMemoryBufferImplSurfaceTexture::CreateFromHandle( 33 const gfx::GpuMemoryBufferHandle& handle, 34 const gfx::Size& size, 35 unsigned internalformat, 36 const DestructionCallback& callback) { 37 DCHECK(IsFormatSupported(internalformat)); 38 39 ANativeWindow* native_window = 40 SurfaceTextureLookup::GetInstance()->AcquireNativeWidget( 41 handle.surface_texture_id.primary_id, 42 handle.surface_texture_id.secondary_id); 43 if (!native_window) 44 return scoped_ptr<GpuMemoryBufferImpl>(); 45 46 ANativeWindow_setBuffersGeometry( 47 native_window, size.width(), size.height(), WindowFormat(internalformat)); 48 49 return make_scoped_ptr<GpuMemoryBufferImpl>( 50 new GpuMemoryBufferImplSurfaceTexture(size, 51 internalformat, 52 callback, 53 handle.surface_texture_id, 54 native_window)); 55} 56 57// static 58bool GpuMemoryBufferImplSurfaceTexture::IsFormatSupported( 59 unsigned internalformat) { 60 switch (internalformat) { 61 case GL_RGBA8_OES: 62 return true; 63 default: 64 return false; 65 } 66} 67 68// static 69bool GpuMemoryBufferImplSurfaceTexture::IsUsageSupported(unsigned usage) { 70 switch (usage) { 71 case GL_IMAGE_MAP_CHROMIUM: 72 return true; 73 default: 74 return false; 75 } 76} 77 78// static 79bool GpuMemoryBufferImplSurfaceTexture::IsConfigurationSupported( 80 unsigned internalformat, 81 unsigned usage) { 82 return IsFormatSupported(internalformat) && IsUsageSupported(usage); 83} 84 85// static 86int GpuMemoryBufferImplSurfaceTexture::WindowFormat(unsigned internalformat) { 87 switch (internalformat) { 88 case GL_RGBA8_OES: 89 return WINDOW_FORMAT_RGBA_8888; 90 default: 91 NOTREACHED(); 92 return 0; 93 } 94} 95 96void* GpuMemoryBufferImplSurfaceTexture::Map() { 97 TRACE_EVENT0("gpu", "GpuMemoryBufferImplSurfaceTexture::Map"); 98 99 DCHECK(!mapped_); 100 DCHECK(native_window_); 101 ANativeWindow_Buffer buffer; 102 int status = ANativeWindow_lock(native_window_, &buffer, NULL); 103 if (status) { 104 VLOG(1) << "ANativeWindow_lock failed with error code: " << status; 105 return NULL; 106 } 107 108 DCHECK_LE(size_.width(), buffer.stride); 109 stride_ = buffer.stride * BytesPerPixel(internalformat_); 110 mapped_ = true; 111 return buffer.bits; 112} 113 114void GpuMemoryBufferImplSurfaceTexture::Unmap() { 115 TRACE_EVENT0("gpu", "GpuMemoryBufferImplSurfaceTexture::Unmap"); 116 117 DCHECK(mapped_); 118 ANativeWindow_unlockAndPost(native_window_); 119 mapped_ = false; 120} 121 122uint32 GpuMemoryBufferImplSurfaceTexture::GetStride() const { return stride_; } 123 124gfx::GpuMemoryBufferHandle GpuMemoryBufferImplSurfaceTexture::GetHandle() 125 const { 126 gfx::GpuMemoryBufferHandle handle; 127 handle.type = gfx::SURFACE_TEXTURE_BUFFER; 128 handle.surface_texture_id = surface_texture_id_; 129 return handle; 130} 131 132} // namespace content 133