Save errno for logging before potentially overwriting it.
[chromium-blink-merge.git] / content / browser / gpu / gpu_surface_tracker.cc
blob350e6f3831c3f4077229eff8355b7c915133b03e
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)
19 namespace content {
21 namespace {
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 {
35 public:
36 SurfaceRefPluginWindow(const gfx::PluginWindowHandle& surface_ref);
37 private:
38 virtual ~SurfaceRefPluginWindow();
39 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.";
53 SurfaceRefPluginWindow::~SurfaceRefPluginWindow() {
54 if (surface_ != gfx::kNullPluginWindow) {
55 BrowserThread::PostTask(BrowserThread::UI,
56 FROM_HERE,
57 base::Bind(&ReleasePermanentXIDDispatcher,
58 surface_));
61 #endif // defined(TOOLKIT_GTK)
62 } // anonymous
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);
84 return surface_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;
98 return 0;
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;
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,
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;
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()
181 : renderer_id(0),
182 render_widget_id(0),
183 native_widget(gfx::kNullAcceleratedWidget) { }
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) { }
197 GpuSurfaceTracker::SurfaceInfo::~SurfaceInfo() { }
200 } // namespace content