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.
5 #include "content/browser/gpu/gpu_surface_tracker.h"
7 #if defined(OS_ANDROID)
8 #include <android/native_window_jni.h>
9 #endif // defined(OS_ANDROID)
11 #include "base/logging.h"
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)
22 #if defined(TOOLKIT_GTK)
24 void ReleasePermanentXIDDispatcher(
25 const gfx::PluginWindowHandle
& surface
) {
26 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
28 GtkNativeViewManager
* manager
= GtkNativeViewManager::GetInstance();
29 manager
->ReleasePermanentXID(surface
);
32 // Implementation of SurfaceRef that allows GTK to ref and unref the
33 // surface with the GtkNativeViewManager.
34 class SurfaceRefPluginWindow
: public GpuSurfaceTracker::SurfaceRef
{
36 SurfaceRefPluginWindow(const gfx::PluginWindowHandle
& surface_ref
);
38 virtual ~SurfaceRefPluginWindow();
39 gfx::PluginWindowHandle surface_
;
42 SurfaceRefPluginWindow::SurfaceRefPluginWindow(
43 const gfx::PluginWindowHandle
& surface
)
45 if (surface_
!= gfx::kNullPluginWindow
) {
46 GtkNativeViewManager
* manager
= GtkNativeViewManager::GetInstance();
47 if (!manager
->AddRefPermanentXID(surface_
)) {
48 LOG(ERROR
) << "Surface " << surface
<< " cannot be referenced.";
53 SurfaceRefPluginWindow::~SurfaceRefPluginWindow() {
54 if (surface_
!= gfx::kNullPluginWindow
) {
55 BrowserThread::PostTask(BrowserThread::UI
,
57 base::Bind(&ReleasePermanentXIDDispatcher
,
61 #endif // defined(TOOLKIT_GTK)
64 GpuSurfaceTracker::GpuSurfaceTracker()
65 : next_surface_id_(1) {
66 GpuSurfaceLookup::InitInstance(this);
69 GpuSurfaceTracker::~GpuSurfaceTracker() {
70 GpuSurfaceLookup::InitInstance(NULL
);
73 GpuSurfaceTracker
* GpuSurfaceTracker::GetInstance() {
74 return Singleton
<GpuSurfaceTracker
>::get();
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
);
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();
92 const SurfaceInfo
& info
= it
->second
;
93 if (info
.renderer_id
== renderer_id
&&
94 info
.render_widget_id
== render_widget_id
) {
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
);
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
);
116 bool GpuSurfaceTracker::GetRenderWidgetIDForSurface(int surface_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())
123 const SurfaceInfo
& info
= it
->second
;
124 if (!info
.handle
.is_transport())
126 *renderer_id
= info
.renderer_id
;
127 *render_widget_id
= info
.render_widget_id
;
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)
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
;
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
;
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)
161 return it
->second
.native_widget
;
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
;
175 std::size_t GpuSurfaceTracker::GetSurfaceCount() {
176 base::AutoLock
lock(lock_
);
177 return surface_map_
.size();
180 GpuSurfaceTracker::SurfaceInfo::SurfaceInfo()
183 native_widget(gfx::kNullAcceleratedWidget
) { }
185 GpuSurfaceTracker::SurfaceInfo::SurfaceInfo(
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
),
195 surface_ref(surface_ref
) { }
197 GpuSurfaceTracker::SurfaceInfo::~SurfaceInfo() { }
200 } // namespace content