Home | History | Annotate | Download | only in client
      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 
     12 namespace content {
     13 
     14 GpuMemoryBufferImplSurfaceTexture::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 
     26 GpuMemoryBufferImplSurfaceTexture::~GpuMemoryBufferImplSurfaceTexture() {
     27   ANativeWindow_release(native_window_);
     28 }
     29 
     30 // static
     31 scoped_ptr<GpuMemoryBufferImpl>
     32 GpuMemoryBufferImplSurfaceTexture::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
     58 bool 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
     69 bool 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
     79 bool GpuMemoryBufferImplSurfaceTexture::IsConfigurationSupported(
     80     unsigned internalformat,
     81     unsigned usage) {
     82   return IsFormatSupported(internalformat) && IsUsageSupported(usage);
     83 }
     84 
     85 // static
     86 int 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 
     96 void* 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 
    114 void GpuMemoryBufferImplSurfaceTexture::Unmap() {
    115   TRACE_EVENT0("gpu", "GpuMemoryBufferImplSurfaceTexture::Unmap");
    116 
    117   DCHECK(mapped_);
    118   ANativeWindow_unlockAndPost(native_window_);
    119   mapped_ = false;
    120 }
    121 
    122 uint32 GpuMemoryBufferImplSurfaceTexture::GetStride() const { return stride_; }
    123 
    124 gfx::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