• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
ReleasePermanentXIDDispatcher(const gfx::PluginWindowHandle & surface)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 
SurfaceRefPluginWindow(const gfx::PluginWindowHandle & surface)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 
~SurfaceRefPluginWindow()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 
GpuSurfaceTracker()64 GpuSurfaceTracker::GpuSurfaceTracker()
65     : next_surface_id_(1) {
66   GpuSurfaceLookup::InitInstance(this);
67 }
68 
~GpuSurfaceTracker()69 GpuSurfaceTracker::~GpuSurfaceTracker() {
70   GpuSurfaceLookup::InitInstance(NULL);
71 }
72 
GetInstance()73 GpuSurfaceTracker* GpuSurfaceTracker::GetInstance() {
74   return Singleton<GpuSurfaceTracker>::get();
75 }
76 
AddSurfaceForRenderer(int renderer_id,int render_widget_id)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 
LookupSurfaceForRenderer(int renderer_id,int render_widget_id)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 
AddSurfaceForNativeWidget(gfx::AcceleratedWidget widget)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 
RemoveSurface(int surface_id)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 
GetRenderWidgetIDForSurface(int surface_id,int * renderer_id,int * render_widget_id)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 
SetSurfaceHandle(int surface_id,const gfx::GLSurfaceHandle & handle)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 
GetSurfaceHandle(int surface_id)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 
AcquireNativeWidget(int surface_id)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 
SetNativeWidget(int surface_id,gfx::AcceleratedWidget widget,SurfaceRef * surface_ref)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 
GetSurfaceCount()175 std::size_t GpuSurfaceTracker::GetSurfaceCount() {
176   base::AutoLock lock(lock_);
177   return surface_map_.size();
178 }
179 
SurfaceInfo()180 GpuSurfaceTracker::SurfaceInfo::SurfaceInfo()
181    : renderer_id(0),
182      render_widget_id(0),
183      native_widget(gfx::kNullAcceleratedWidget) { }
184 
SurfaceInfo(int renderer_id,int render_widget_id,const gfx::AcceleratedWidget & native_widget,const gfx::GLSurfaceHandle & handle,const scoped_refptr<SurfaceRef> & surface_ref)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 
~SurfaceInfo()197 GpuSurfaceTracker::SurfaceInfo::~SurfaceInfo() { }
198 
199 
200 }  // namespace content
201