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
13namespace content {
14
15GpuSurfaceTracker::GpuSurfaceTracker()
16    : next_surface_id_(1) {
17  GpuSurfaceLookup::InitInstance(this);
18}
19
20GpuSurfaceTracker::~GpuSurfaceTracker() {
21  GpuSurfaceLookup::InitInstance(NULL);
22}
23
24GpuSurfaceTracker* GpuSurfaceTracker::GetInstance() {
25  return Singleton<GpuSurfaceTracker>::get();
26}
27
28int GpuSurfaceTracker::AddSurfaceForRenderer(int renderer_id,
29                                             int render_widget_id) {
30  base::AutoLock lock(lock_);
31  int surface_id = next_surface_id_++;
32  surface_map_[surface_id] =
33      SurfaceInfo(renderer_id, render_widget_id, gfx::kNullAcceleratedWidget,
34                  gfx::GLSurfaceHandle(), NULL);
35  return surface_id;
36}
37
38int GpuSurfaceTracker::LookupSurfaceForRenderer(int renderer_id,
39                                                int render_widget_id) {
40  base::AutoLock lock(lock_);
41  for (SurfaceMap::iterator it = surface_map_.begin(); it != surface_map_.end();
42       ++it) {
43    const SurfaceInfo& info = it->second;
44    if (info.renderer_id == renderer_id &&
45        info.render_widget_id == render_widget_id) {
46      return it->first;
47    }
48  }
49  return 0;
50}
51
52int GpuSurfaceTracker::AddSurfaceForNativeWidget(
53    gfx::AcceleratedWidget widget) {
54  base::AutoLock lock(lock_);
55  int surface_id = next_surface_id_++;
56  surface_map_[surface_id] =
57      SurfaceInfo(0, 0, widget, gfx::GLSurfaceHandle(), NULL);
58  return surface_id;
59}
60
61void GpuSurfaceTracker::RemoveSurface(int surface_id) {
62  base::AutoLock lock(lock_);
63  DCHECK(surface_map_.find(surface_id) != surface_map_.end());
64  surface_map_.erase(surface_id);
65}
66
67bool GpuSurfaceTracker::GetRenderWidgetIDForSurface(int surface_id,
68                                                    int* renderer_id,
69                                                    int* render_widget_id) {
70  base::AutoLock lock(lock_);
71  SurfaceMap::iterator it = surface_map_.find(surface_id);
72  if (it == surface_map_.end())
73    return false;
74  const SurfaceInfo& info = it->second;
75  if (!info.handle.is_transport())
76    return false;
77  *renderer_id = info.renderer_id;
78  *render_widget_id = info.render_widget_id;
79  return true;
80}
81
82void GpuSurfaceTracker::SetSurfaceHandle(int surface_id,
83                                         const gfx::GLSurfaceHandle& handle) {
84  base::AutoLock lock(lock_);
85  DCHECK(surface_map_.find(surface_id) != surface_map_.end());
86  SurfaceInfo& info = surface_map_[surface_id];
87  info.handle = handle;
88}
89
90gfx::GLSurfaceHandle GpuSurfaceTracker::GetSurfaceHandle(int surface_id) {
91  base::AutoLock lock(lock_);
92  SurfaceMap::iterator it = surface_map_.find(surface_id);
93  if (it == surface_map_.end())
94    return gfx::GLSurfaceHandle();
95  return it->second.handle;
96}
97
98gfx::AcceleratedWidget GpuSurfaceTracker::AcquireNativeWidget(int surface_id) {
99  base::AutoLock lock(lock_);
100  SurfaceMap::iterator it = surface_map_.find(surface_id);
101  if (it == surface_map_.end())
102    return gfx::kNullAcceleratedWidget;
103
104#if defined(OS_ANDROID)
105  if (it->second.native_widget != gfx::kNullAcceleratedWidget)
106    ANativeWindow_acquire(it->second.native_widget);
107#endif  // defined(OS_ANDROID)
108
109  return it->second.native_widget;
110}
111
112void GpuSurfaceTracker::SetNativeWidget(
113    int surface_id, gfx::AcceleratedWidget widget,
114    SurfaceRef* surface_ref) {
115  base::AutoLock lock(lock_);
116  SurfaceMap::iterator it = surface_map_.find(surface_id);
117  DCHECK(it != surface_map_.end());
118  SurfaceInfo& info = it->second;
119  info.native_widget = widget;
120  info.surface_ref = surface_ref;
121}
122
123std::size_t GpuSurfaceTracker::GetSurfaceCount() {
124  base::AutoLock lock(lock_);
125  return surface_map_.size();
126}
127
128GpuSurfaceTracker::SurfaceInfo::SurfaceInfo()
129   : renderer_id(0),
130     render_widget_id(0),
131     native_widget(gfx::kNullAcceleratedWidget) { }
132
133GpuSurfaceTracker::SurfaceInfo::SurfaceInfo(
134    int renderer_id,
135    int render_widget_id,
136    const gfx::AcceleratedWidget& native_widget,
137    const gfx::GLSurfaceHandle& handle,
138    const scoped_refptr<SurfaceRef>& surface_ref)
139    : renderer_id(renderer_id),
140      render_widget_id(render_widget_id),
141      native_widget(native_widget),
142      handle(handle),
143      surface_ref(surface_ref) { }
144
145GpuSurfaceTracker::SurfaceInfo::~SurfaceInfo() { }
146
147
148}  // namespace content
149