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 : GpuMemoryBufferImpl(size, internalformat), 18 native_window_(NULL), 19 stride_(0u) {} 20 21GpuMemoryBufferImplSurfaceTexture::~GpuMemoryBufferImplSurfaceTexture() { 22 if (native_window_) 23 ANativeWindow_release(native_window_); 24} 25 26// static 27bool GpuMemoryBufferImplSurfaceTexture::IsFormatSupported( 28 unsigned internalformat) { 29 switch (internalformat) { 30 case GL_RGBA8_OES: 31 return true; 32 default: 33 return false; 34 } 35} 36 37// static 38bool GpuMemoryBufferImplSurfaceTexture::IsUsageSupported(unsigned usage) { 39 switch (usage) { 40 case GL_IMAGE_MAP_CHROMIUM: 41 return true; 42 default: 43 return false; 44 } 45} 46 47// static 48bool GpuMemoryBufferImplSurfaceTexture::IsConfigurationSupported( 49 unsigned internalformat, 50 unsigned usage) { 51 return IsFormatSupported(internalformat) && IsUsageSupported(usage); 52} 53 54// static 55int GpuMemoryBufferImplSurfaceTexture::WindowFormat(unsigned internalformat) { 56 switch (internalformat) { 57 case GL_RGBA8_OES: 58 return WINDOW_FORMAT_RGBA_8888; 59 default: 60 NOTREACHED(); 61 return 0; 62 } 63} 64 65bool GpuMemoryBufferImplSurfaceTexture::InitializeFromHandle( 66 gfx::GpuMemoryBufferHandle handle) { 67 TRACE_EVENT0("gpu", 68 "GpuMemoryBufferImplSurfaceTexture::InitializeFromHandle"); 69 70 DCHECK(IsFormatSupported(internalformat_)); 71 DCHECK(!native_window_); 72 native_window_ = SurfaceTextureLookup::GetInstance()->AcquireNativeWidget( 73 handle.surface_texture_id.primary_id, 74 handle.surface_texture_id.secondary_id); 75 if (!native_window_) 76 return false; 77 78 ANativeWindow_setBuffersGeometry(native_window_, 79 size_.width(), 80 size_.height(), 81 WindowFormat(internalformat_)); 82 83 surface_texture_id_ = handle.surface_texture_id; 84 return true; 85} 86 87void* GpuMemoryBufferImplSurfaceTexture::Map() { 88 TRACE_EVENT0("gpu", "GpuMemoryBufferImplSurfaceTexture::Map"); 89 90 DCHECK(!mapped_); 91 DCHECK(native_window_); 92 ANativeWindow_Buffer buffer; 93 int status = ANativeWindow_lock(native_window_, &buffer, NULL); 94 if (status) { 95 VLOG(1) << "ANativeWindow_lock failed with error code: " << status; 96 return NULL; 97 } 98 99 DCHECK_LE(size_.width(), buffer.stride); 100 stride_ = buffer.stride * BytesPerPixel(internalformat_); 101 mapped_ = true; 102 return buffer.bits; 103} 104 105void GpuMemoryBufferImplSurfaceTexture::Unmap() { 106 TRACE_EVENT0("gpu", "GpuMemoryBufferImplSurfaceTexture::Unmap"); 107 108 DCHECK(mapped_); 109 ANativeWindow_unlockAndPost(native_window_); 110 mapped_ = false; 111} 112 113uint32 GpuMemoryBufferImplSurfaceTexture::GetStride() const { return stride_; } 114 115gfx::GpuMemoryBufferHandle GpuMemoryBufferImplSurfaceTexture::GetHandle() 116 const { 117 gfx::GpuMemoryBufferHandle handle; 118 handle.type = gfx::SURFACE_TEXTURE_BUFFER; 119 handle.surface_texture_id = surface_texture_id_; 120 return handle; 121} 122 123} // namespace content 124