Home | History | Annotate | Download | only in gpu
      1 // Copyright (c) 2012 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/browser/gpu/gpu_surface_tracker.h"
      6 
      7 #if defined(OS_ANDROID)
      8 #include <android/native_window_jni.h>
      9 #endif  // defined(OS_ANDROID)
     10 
     11 #include "base/logging.h"
     12 
     13 #if defined(TOOLKIT_GTK)
     14 #include "base/bind.h"
     15 #include "content/public/browser/browser_thread.h"
     16 #include "ui/gfx/gtk_native_view_id_manager.h"
     17 #endif  // defined(TOOLKIT_GTK)
     18 
     19 namespace content {
     20 
     21 namespace {
     22 #if defined(TOOLKIT_GTK)
     23 
     24 void ReleasePermanentXIDDispatcher(
     25     const gfx::PluginWindowHandle& surface) {
     26   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     27 
     28   GtkNativeViewManager* manager = GtkNativeViewManager::GetInstance();
     29   manager->ReleasePermanentXID(surface);
     30 }
     31 
     32 // Implementation of SurfaceRef that allows GTK to ref and unref the
     33 // surface with the GtkNativeViewManager.
     34 class SurfaceRefPluginWindow : public GpuSurfaceTracker::SurfaceRef {
     35   public:
     36    SurfaceRefPluginWindow(const gfx::PluginWindowHandle& surface_ref);
     37   private:
     38    virtual ~SurfaceRefPluginWindow();
     39    gfx::PluginWindowHandle surface_;
     40 };
     41 
     42 SurfaceRefPluginWindow::SurfaceRefPluginWindow(
     43     const gfx::PluginWindowHandle& surface)
     44     : surface_(surface) {
     45   if (surface_ != gfx::kNullPluginWindow) {
     46     GtkNativeViewManager* manager = GtkNativeViewManager::GetInstance();
     47     if (!manager->AddRefPermanentXID(surface_)) {
     48       LOG(ERROR) << "Surface " << surface << " cannot be referenced.";
     49     }
     50   }
     51 }
     52 
     53 SurfaceRefPluginWindow::~SurfaceRefPluginWindow() {
     54   if (surface_ != gfx::kNullPluginWindow) {
     55     BrowserThread::PostTask(BrowserThread::UI,
     56                             FROM_HERE,
     57                             base::Bind(&ReleasePermanentXIDDispatcher,
     58                                        surface_));
     59   }
     60 }
     61 #endif  // defined(TOOLKIT_GTK)
     62 }  // anonymous
     63 
     64 GpuSurfaceTracker::GpuSurfaceTracker()
     65     : next_surface_id_(1) {
     66   GpuSurfaceLookup::InitInstance(this);
     67 }
     68 
     69 GpuSurfaceTracker::~GpuSurfaceTracker() {
     70   GpuSurfaceLookup::InitInstance(NULL);
     71 }
     72 
     73 GpuSurfaceTracker* GpuSurfaceTracker::GetInstance() {
     74   return Singleton<GpuSurfaceTracker>::get();
     75 }
     76 
     77 int GpuSurfaceTracker::AddSurfaceForRenderer(int renderer_id,
     78                                              int render_widget_id) {
     79   base::AutoLock lock(lock_);
     80   int surface_id = next_surface_id_++;
     81   surface_map_[surface_id] =
     82       SurfaceInfo(renderer_id, render_widget_id, gfx::kNullAcceleratedWidget,
     83                   gfx::GLSurfaceHandle(), NULL);
     84   return surface_id;
     85 }
     86 
     87 int GpuSurfaceTracker::LookupSurfaceForRenderer(int renderer_id,
     88                                                 int render_widget_id) {
     89   base::AutoLock lock(lock_);
     90   for (SurfaceMap::iterator it = surface_map_.begin(); it != surface_map_.end();
     91        ++it) {
     92     const SurfaceInfo& info = it->second;
     93     if (info.renderer_id == renderer_id &&
     94         info.render_widget_id == render_widget_id) {
     95       return it->first;
     96     }
     97   }
     98   return 0;
     99 }
    100 
    101 int GpuSurfaceTracker::AddSurfaceForNativeWidget(
    102     gfx::AcceleratedWidget widget) {
    103   base::AutoLock lock(lock_);
    104   int surface_id = next_surface_id_++;
    105   surface_map_[surface_id] =
    106       SurfaceInfo(0, 0, widget, gfx::GLSurfaceHandle(), NULL);
    107   return surface_id;
    108 }
    109 
    110 void GpuSurfaceTracker::RemoveSurface(int surface_id) {
    111   base::AutoLock lock(lock_);
    112   DCHECK(surface_map_.find(surface_id) != surface_map_.end());
    113   surface_map_.erase(surface_id);
    114 }
    115 
    116 bool GpuSurfaceTracker::GetRenderWidgetIDForSurface(int surface_id,
    117                                                     int* renderer_id,
    118                                                     int* render_widget_id) {
    119   base::AutoLock lock(lock_);
    120   SurfaceMap::iterator it = surface_map_.find(surface_id);
    121   if (it == surface_map_.end())
    122     return false;
    123   const SurfaceInfo& info = it->second;
    124   if (!info.handle.is_transport())
    125     return false;
    126   *renderer_id = info.renderer_id;
    127   *render_widget_id = info.render_widget_id;
    128   return true;
    129 }
    130 
    131 void GpuSurfaceTracker::SetSurfaceHandle(int surface_id,
    132                                          const gfx::GLSurfaceHandle& handle) {
    133   base::AutoLock lock(lock_);
    134   DCHECK(surface_map_.find(surface_id) != surface_map_.end());
    135   SurfaceInfo& info = surface_map_[surface_id];
    136   info.handle = handle;
    137 #if defined(TOOLKIT_GTK)
    138   info.surface_ref = new SurfaceRefPluginWindow(handle.handle);
    139 #endif  // defined(TOOLKIT_GTK)
    140 }
    141 
    142 gfx::GLSurfaceHandle GpuSurfaceTracker::GetSurfaceHandle(int surface_id) {
    143   base::AutoLock lock(lock_);
    144   SurfaceMap::iterator it = surface_map_.find(surface_id);
    145   if (it == surface_map_.end())
    146     return gfx::GLSurfaceHandle();
    147   return it->second.handle;
    148 }
    149 
    150 gfx::AcceleratedWidget GpuSurfaceTracker::AcquireNativeWidget(int surface_id) {
    151   base::AutoLock lock(lock_);
    152   SurfaceMap::iterator it = surface_map_.find(surface_id);
    153   if (it == surface_map_.end())
    154     return gfx::kNullAcceleratedWidget;
    155 
    156 #if defined(OS_ANDROID)
    157   if (it->second.native_widget != gfx::kNullAcceleratedWidget)
    158     ANativeWindow_acquire(it->second.native_widget);
    159 #endif  // defined(OS_ANDROID)
    160 
    161   return it->second.native_widget;
    162 }
    163 
    164 void GpuSurfaceTracker::SetNativeWidget(
    165     int surface_id, gfx::AcceleratedWidget widget,
    166     SurfaceRef* surface_ref) {
    167   base::AutoLock lock(lock_);
    168   SurfaceMap::iterator it = surface_map_.find(surface_id);
    169   DCHECK(it != surface_map_.end());
    170   SurfaceInfo& info = it->second;
    171   info.native_widget = widget;
    172   info.surface_ref = surface_ref;
    173 }
    174 
    175 std::size_t GpuSurfaceTracker::GetSurfaceCount() {
    176   base::AutoLock lock(lock_);
    177   return surface_map_.size();
    178 }
    179 
    180 GpuSurfaceTracker::SurfaceInfo::SurfaceInfo()
    181    : renderer_id(0),
    182      render_widget_id(0),
    183      native_widget(gfx::kNullAcceleratedWidget) { }
    184 
    185 GpuSurfaceTracker::SurfaceInfo::SurfaceInfo(
    186     int renderer_id,
    187     int render_widget_id,
    188     const gfx::AcceleratedWidget& native_widget,
    189     const gfx::GLSurfaceHandle& handle,
    190     const scoped_refptr<SurfaceRef>& surface_ref)
    191     : renderer_id(renderer_id),
    192       render_widget_id(render_widget_id),
    193       native_widget(native_widget),
    194       handle(handle),
    195       surface_ref(surface_ref) { }
    196 
    197 GpuSurfaceTracker::SurfaceInfo::~SurfaceInfo() { }
    198 
    199 
    200 }  // namespace content
    201