OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "gpu/command_buffer/service/stream_texture_manager_in_process_android.h
" | 5 #include "gpu/command_buffer/service/stream_texture_manager_in_process_android.h
" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/callback.h" | 8 #include "base/callback.h" |
9 #include "gpu/command_buffer/service/texture_manager.h" | 9 #include "gpu/command_buffer/service/texture_manager.h" |
10 #include "ui/gfx/geometry/size.h" | 10 #include "ui/gfx/geometry/size.h" |
11 #include "ui/gl/android/surface_texture.h" | 11 #include "ui/gl/android/surface_texture.h" |
12 #include "ui/gl/gl_bindings.h" | 12 #include "ui/gl/gl_bindings.h" |
13 #include "ui/gl/gl_image.h" | 13 #include "ui/gl/gl_image.h" |
14 | 14 |
15 namespace gpu { | 15 namespace gpu { |
16 | 16 |
17 namespace { | 17 // Simply wraps a SurfaceTexture reference as a GLImage. |
| 18 class StreamTextureManagerInProcess::GLImage : public gl::GLImage { |
| 19 public: |
| 20 GLImage(uint32 texture_id, |
| 21 gles2::TextureManager* texture_manager, |
| 22 const scoped_refptr<gfx::SurfaceTexture>& surface_texture, |
| 23 const base::Closure& release_callback) |
| 24 : texture_id_(texture_id), |
| 25 texture_manager_(texture_manager), |
| 26 surface_texture_(surface_texture), |
| 27 release_callback_(release_callback) {} |
18 | 28 |
19 // Simply wraps a SurfaceTexture reference as a GLImage. | 29 void SetSize(const gfx::Size& size) { size_ = size; } |
20 class GLImageImpl : public gl::GLImage { | 30 scoped_refptr<gfx::SurfaceTexture> GetSurfaceTexture() { |
21 public: | 31 return surface_texture_; |
22 GLImageImpl(uint32 texture_id, | 32 } |
23 gles2::TextureManager* texture_manager, | |
24 const scoped_refptr<gfx::SurfaceTexture>& surface_texture, | |
25 const base::Closure& release_callback); | |
26 | 33 |
27 // implement gl::GLImage | 34 // implement gl::GLImage |
28 void Destroy(bool have_context) override; | 35 void Destroy(bool have_context) override { NOTREACHED(); } |
29 gfx::Size GetSize() override; | 36 gfx::Size GetSize() override { return gfx::Size(); } |
30 unsigned GetInternalFormat() override; | 37 unsigned GetInternalFormat() override { return GL_RGBA; } |
31 bool BindTexImage(unsigned target) override; | 38 bool BindTexImage(unsigned target) override { |
32 void ReleaseTexImage(unsigned target) override; | 39 NOTREACHED(); |
33 bool CopyTexImage(unsigned target) override; | 40 return false; |
| 41 } |
| 42 void ReleaseTexImage(unsigned target) override { NOTREACHED(); } |
| 43 bool CopyTexImage(unsigned target) override { |
| 44 if (target != GL_TEXTURE_EXTERNAL_OES) |
| 45 return false; |
| 46 |
| 47 GLint texture_id; |
| 48 glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texture_id); |
| 49 DCHECK(texture_id); |
| 50 |
| 51 // The following code only works if we're being asked to copy into |
| 52 // |texture_id_|. Copying into a different texture is not supported. |
| 53 if (static_cast<unsigned>(texture_id) != texture_id_) |
| 54 return false; |
| 55 |
| 56 surface_texture_->UpdateTexImage(); |
| 57 |
| 58 gles2::Texture* texture = |
| 59 texture_manager_->GetTextureForServiceId(texture_id_); |
| 60 if (texture) { |
| 61 // By setting image state to UNBOUND instead of COPIED we ensure that |
| 62 // CopyTexImage() is called each time the surface texture is used for |
| 63 // drawing. |
| 64 texture->SetLevelImage(GL_TEXTURE_EXTERNAL_OES, 0, this, |
| 65 gles2::Texture::UNBOUND); |
| 66 } |
| 67 return true; |
| 68 } |
34 bool CopyTexSubImage(unsigned target, | 69 bool CopyTexSubImage(unsigned target, |
35 const gfx::Point& offset, | 70 const gfx::Point& offset, |
36 const gfx::Rect& rect) override; | 71 const gfx::Rect& rect) override { |
| 72 return false; |
| 73 } |
37 bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget, | 74 bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget, |
38 int z_order, | 75 int z_order, |
39 gfx::OverlayTransform transform, | 76 gfx::OverlayTransform transform, |
40 const gfx::Rect& bounds_rect, | 77 const gfx::Rect& bounds_rect, |
41 const gfx::RectF& crop_rect) override; | 78 const gfx::RectF& crop_rect) override { |
| 79 NOTREACHED(); |
| 80 return false; |
| 81 } |
42 void OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd, | 82 void OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd, |
43 uint64_t process_tracing_id, | 83 uint64_t process_tracing_id, |
44 const std::string& dump_name) override; | 84 const std::string& dump_name) override { |
| 85 // TODO(ericrk): Implement GLImage OnMemoryDump. crbug.com/514914 |
| 86 } |
45 | 87 |
46 private: | 88 private: |
47 ~GLImageImpl() override; | 89 ~GLImage() override { release_callback_.Run(); } |
48 | 90 |
49 uint32 texture_id_; | 91 uint32 texture_id_; |
50 gles2::TextureManager* texture_manager_; | 92 gles2::TextureManager* texture_manager_; |
51 scoped_refptr<gfx::SurfaceTexture> surface_texture_; | 93 scoped_refptr<gfx::SurfaceTexture> surface_texture_; |
52 base::Closure release_callback_; | 94 base::Closure release_callback_; |
| 95 gfx::Size size_; |
53 | 96 |
54 DISALLOW_COPY_AND_ASSIGN(GLImageImpl); | 97 DISALLOW_COPY_AND_ASSIGN(GLImage); |
55 }; | 98 }; |
56 | 99 |
57 GLImageImpl::GLImageImpl( | 100 StreamTextureManagerInProcess::StreamTextureManagerInProcess() |
58 uint32 texture_id, | 101 : weak_factory_(this) { |
59 gles2::TextureManager* texture_manager, | 102 next_id_.GetNext(); |
60 const scoped_refptr<gfx::SurfaceTexture>& surface_texture, | |
61 const base::Closure& release_callback) | |
62 : texture_id_(texture_id), | |
63 texture_manager_(texture_manager), | |
64 surface_texture_(surface_texture), | |
65 release_callback_(release_callback) {} | |
66 | |
67 GLImageImpl::~GLImageImpl() { | |
68 release_callback_.Run(); | |
69 } | 103 } |
70 | 104 |
71 void GLImageImpl::Destroy(bool have_context) { | |
72 NOTREACHED(); | |
73 } | |
74 | |
75 gfx::Size GLImageImpl::GetSize() { | |
76 return gfx::Size(); | |
77 } | |
78 | |
79 unsigned GLImageImpl::GetInternalFormat() { | |
80 return GL_RGBA; | |
81 } | |
82 | |
83 bool GLImageImpl::BindTexImage(unsigned target) { | |
84 NOTREACHED(); | |
85 return false; | |
86 } | |
87 | |
88 void GLImageImpl::ReleaseTexImage(unsigned target) { | |
89 NOTREACHED(); | |
90 } | |
91 | |
92 bool GLImageImpl::CopyTexImage(unsigned target) { | |
93 if (target != GL_TEXTURE_EXTERNAL_OES) | |
94 return false; | |
95 | |
96 GLint texture_id; | |
97 glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texture_id); | |
98 DCHECK(texture_id); | |
99 | |
100 // The following code only works if we're being asked to copy into | |
101 // |texture_id_|. Copying into a different texture is not supported. | |
102 if (static_cast<unsigned>(texture_id) != texture_id_) | |
103 return false; | |
104 | |
105 surface_texture_->UpdateTexImage(); | |
106 | |
107 gles2::Texture* texture = | |
108 texture_manager_->GetTextureForServiceId(texture_id_); | |
109 if (texture) { | |
110 // By setting image state to UNBOUND instead of COPIED we ensure that | |
111 // CopyTexImage() is called each time the surface texture is used for | |
112 // drawing. | |
113 texture->SetLevelImage(GL_TEXTURE_EXTERNAL_OES, 0, this, | |
114 gles2::Texture::UNBOUND); | |
115 } | |
116 return true; | |
117 } | |
118 | |
119 bool GLImageImpl::CopyTexSubImage(unsigned target, | |
120 const gfx::Point& offset, | |
121 const gfx::Rect& rect) { | |
122 return false; | |
123 } | |
124 | |
125 bool GLImageImpl::ScheduleOverlayPlane(gfx::AcceleratedWidget widget, | |
126 int z_order, | |
127 gfx::OverlayTransform transform, | |
128 const gfx::Rect& bounds_rect, | |
129 const gfx::RectF& crop_rect) { | |
130 NOTREACHED(); | |
131 return false; | |
132 } | |
133 | |
134 void GLImageImpl::OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd, | |
135 uint64_t process_tracing_id, | |
136 const std::string& dump_name) { | |
137 // TODO(ericrk): Implement GLImage OnMemoryDump. crbug.com/514914 | |
138 } | |
139 | |
140 } // anonymous namespace | |
141 | |
142 StreamTextureManagerInProcess::StreamTextureManagerInProcess() | |
143 : next_id_(1), weak_factory_(this) {} | |
144 | |
145 StreamTextureManagerInProcess::~StreamTextureManagerInProcess() { | 105 StreamTextureManagerInProcess::~StreamTextureManagerInProcess() { |
146 if (!textures_.empty()) { | 106 if (!images_.empty()) { |
147 LOG(WARNING) << "Undestroyed surface textures while tearing down " | 107 LOG(WARNING) << "Undestroyed surface textures while tearing down " |
148 "StreamTextureManager."; | 108 "StreamTextureManager."; |
149 } | 109 } |
150 } | 110 } |
151 | 111 |
152 GLuint StreamTextureManagerInProcess::CreateStreamTexture( | 112 GLint StreamTextureManagerInProcess::CreateStreamTexture( |
153 uint32 client_texture_id, | 113 uint32 client_texture_id, |
154 gles2::TextureManager* texture_manager) { | 114 gles2::TextureManager* texture_manager) { |
155 CalledOnValidThread(); | 115 CalledOnValidThread(); |
156 | 116 |
157 gles2::TextureRef* texture = texture_manager->GetTexture(client_texture_id); | 117 gles2::TextureRef* texture = texture_manager->GetTexture(client_texture_id); |
158 | 118 |
159 if (!texture || (texture->texture()->target() && | 119 if (!texture || (texture->texture()->target() && |
160 texture->texture()->target() != GL_TEXTURE_EXTERNAL_OES)) { | 120 texture->texture()->target() != GL_TEXTURE_EXTERNAL_OES)) { |
161 return 0; | 121 return 0; |
162 } | 122 } |
163 | 123 |
164 scoped_refptr<gfx::SurfaceTexture> surface_texture( | 124 scoped_refptr<gfx::SurfaceTexture> surface_texture( |
165 gfx::SurfaceTexture::Create(texture->service_id())); | 125 gfx::SurfaceTexture::Create(texture->service_id())); |
166 | 126 |
167 uint32 stream_id = next_id_++; | 127 int32 stream_id = next_id_.GetNext(); |
168 base::Closure release_callback = | 128 base::Closure release_callback = |
169 base::Bind(&StreamTextureManagerInProcess::OnReleaseStreamTexture, | 129 base::Bind(&StreamTextureManagerInProcess::OnReleaseStreamTexture, |
170 weak_factory_.GetWeakPtr(), stream_id); | 130 weak_factory_.GetWeakPtr(), stream_id); |
171 scoped_refptr<gl::GLImage> gl_image( | 131 scoped_refptr<GLImage> gl_image(new GLImage(texture->service_id(), |
172 new GLImageImpl(texture->service_id(), texture_manager, surface_texture, | 132 texture_manager, surface_texture, |
173 release_callback)); | 133 release_callback)); |
174 | 134 |
175 gfx::Size size = gl_image->GetSize(); | 135 gfx::Size size = gl_image->GetSize(); |
176 texture_manager->SetTarget(texture, GL_TEXTURE_EXTERNAL_OES); | 136 texture_manager->SetTarget(texture, GL_TEXTURE_EXTERNAL_OES); |
177 texture_manager->SetLevelInfo(texture, GL_TEXTURE_EXTERNAL_OES, 0, GL_RGBA, | 137 texture_manager->SetLevelInfo(texture, GL_TEXTURE_EXTERNAL_OES, 0, GL_RGBA, |
178 size.width(), size.height(), 1, 0, GL_RGBA, | 138 size.width(), size.height(), 1, 0, GL_RGBA, |
179 GL_UNSIGNED_BYTE, gfx::Rect(size)); | 139 GL_UNSIGNED_BYTE, gfx::Rect(size)); |
180 texture_manager->SetLevelImage(texture, GL_TEXTURE_EXTERNAL_OES, 0, | 140 texture_manager->SetLevelImage(texture, GL_TEXTURE_EXTERNAL_OES, 0, |
181 gl_image.get(), gles2::Texture::UNBOUND); | 141 gl_image.get(), gles2::Texture::UNBOUND); |
182 | 142 |
183 { | 143 { |
184 base::AutoLock lock(map_lock_); | 144 base::AutoLock lock(map_lock_); |
185 textures_[stream_id] = surface_texture; | 145 DCHECK_EQ(static_cast<size_t>(0), images_.count(stream_id)); |
| 146 images_[stream_id] = gl_image.get(); |
186 } | 147 } |
187 | 148 |
188 if (next_id_ == 0) | |
189 next_id_++; | |
190 | |
191 return stream_id; | 149 return stream_id; |
192 } | 150 } |
193 | 151 |
194 void StreamTextureManagerInProcess::OnReleaseStreamTexture(uint32 stream_id) { | 152 void StreamTextureManagerInProcess::SetStreamTextureSize( |
| 153 uint32 client_texture_id, |
| 154 int32 stream_id, |
| 155 size_t width, |
| 156 size_t height, |
| 157 gles2::TextureManager* texture_manager) { |
| 158 CalledOnValidThread(); |
| 159 |
| 160 gles2::TextureRef* texture = texture_manager->GetTexture(client_texture_id); |
| 161 |
| 162 if (!texture || (texture->texture()->target() && |
| 163 texture->texture()->target() != GL_TEXTURE_EXTERNAL_OES)) { |
| 164 return; |
| 165 } |
| 166 |
| 167 scoped_refptr<GLImage> gl_image; |
| 168 { |
| 169 base::AutoLock lock(map_lock_); |
| 170 if (!images_.count(stream_id)) |
| 171 return; |
| 172 gl_image = images_[stream_id]; |
| 173 } |
| 174 |
| 175 gl_image->SetSize(gfx::Size(width, height)); |
| 176 gfx::Size size = gl_image->GetSize(); |
| 177 texture_manager->SetLevelInfo(texture, GL_TEXTURE_EXTERNAL_OES, 0, GL_RGBA, |
| 178 width, height, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, |
| 179 gfx::Rect(size)); |
| 180 texture_manager->SetLevelImage(texture, GL_TEXTURE_EXTERNAL_OES, 0, |
| 181 gl_image.get(), gles2::Texture::UNBOUND); |
| 182 } |
| 183 |
| 184 void StreamTextureManagerInProcess::OnReleaseStreamTexture(int32 stream_id) { |
195 CalledOnValidThread(); | 185 CalledOnValidThread(); |
196 base::AutoLock lock(map_lock_); | 186 base::AutoLock lock(map_lock_); |
197 textures_.erase(stream_id); | 187 DCHECK_EQ(static_cast<size_t>(1), images_.count(stream_id)); |
| 188 images_.erase(stream_id); |
198 } | 189 } |
199 | 190 |
200 // This can get called from any thread. | 191 // This can get called from any thread. |
201 scoped_refptr<gfx::SurfaceTexture> | 192 scoped_refptr<gfx::SurfaceTexture> |
202 StreamTextureManagerInProcess::GetSurfaceTexture(uint32 stream_id) { | 193 StreamTextureManagerInProcess::GetSurfaceTexture(int32 stream_id) { |
203 base::AutoLock lock(map_lock_); | 194 base::AutoLock lock(map_lock_); |
204 TextureMap::const_iterator it = textures_.find(stream_id); | 195 ImageMap::const_iterator it = images_.find(stream_id); |
205 if (it != textures_.end()) | 196 if (it != images_.end()) |
206 return it->second; | 197 return it->second->GetSurfaceTexture(); |
207 | 198 |
208 return NULL; | 199 return nullptr; |
209 } | 200 } |
210 | 201 |
211 } // namespace gpu | 202 } // namespace gpu |
OLD | NEW |