Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(213)

Side by Side Diff: content/common/gpu/media/avda_codec_image.cc

Issue 1892013002: ReleaseOutputBuffer to surface back and front buffers where possible. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Cleanerer. Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "content/common/gpu/media/avda_codec_image.h" 5 #include "content/common/gpu/media/avda_codec_image.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 8
9 #include <memory> 9 #include <memory>
10 10
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 gfx::OverlayTransform transform, 104 gfx::OverlayTransform transform,
105 const gfx::Rect& bounds_rect, 105 const gfx::Rect& bounds_rect,
106 const gfx::RectF& crop_rect) { 106 const gfx::RectF& crop_rect) {
107 // This should only be called when we're rendering to a SurfaceView. 107 // This should only be called when we're rendering to a SurfaceView.
108 if (surface_texture_) { 108 if (surface_texture_) {
109 DVLOG(1) << "Invalid call to ScheduleOverlayPlane; this image is " 109 DVLOG(1) << "Invalid call to ScheduleOverlayPlane; this image is "
110 "SurfaceTexture backed."; 110 "SurfaceTexture backed.";
111 return false; 111 return false;
112 } 112 }
113 113
114 if (codec_buffer_index_ != kInvalidCodecBufferIndex) { 114 ReleaseOutputBuffer(ReleaseMode::RENDER_ONLY);
liberato (no reviews please) 2016/04/22 00:51:06 RENDER_AND_UPDATE, else it will try to wait for fr
DaleCurtis 2016/04/22 01:33:58 Done.
115 media_codec_->ReleaseOutputBuffer(codec_buffer_index_, true); 115 codec_buffer_index_ = kInvalidCodecBufferIndex;
116 codec_buffer_index_ = kInvalidCodecBufferIndex;
117 }
118 return true; 116 return true;
119 } 117 }
120 118
121 void AVDACodecImage::OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd, 119 void AVDACodecImage::OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
122 uint64_t process_tracing_id, 120 uint64_t process_tracing_id,
123 const std::string& dump_name) {} 121 const std::string& dump_name) {}
124 122
125 void AVDACodecImage::UpdateSurfaceTexture(RestoreBindingsMode mode) { 123 void AVDACodecImage::UpdateSurfaceTexture(RestoreBindingsMode mode) {
126 DCHECK(surface_texture_); 124 DCHECK(surface_texture_);
127 125
128 // Render via the media codec if needed.
129 if (!IsCodecBufferOutstanding()) 126 if (!IsCodecBufferOutstanding())
130 return; 127 return;
131 128
132 // The decoder buffer is still pending. 129 ReleaseOutputBuffer(ReleaseMode::RENDER_ONLY);
133 // This must be synchronous, so wait for OnFrameAvailable. 130 DCHECK_EQ(codec_buffer_index_, kUpdateOnly);
134 media_codec_->ReleaseOutputBuffer(codec_buffer_index_, true);
135 {
136 SCOPED_UMA_HISTOGRAM_TIMER("Media.AvdaCodecImage.WaitTimeForFrame");
137 shared_state_->WaitForFrameAvailable();
138 }
139
140 // Don't bother to check if we're rendered again.
141 codec_buffer_index_ = kInvalidCodecBufferIndex; 131 codec_buffer_index_ = kInvalidCodecBufferIndex;
142 132
143 // Swap the rendered image to the front. 133 // Swap the rendered image to the front.
144 std::unique_ptr<ui::ScopedMakeCurrent> scoped_make_current = 134 std::unique_ptr<ui::ScopedMakeCurrent> scoped_make_current =
145 MakeCurrentIfNeeded(); 135 MakeCurrentIfNeeded();
146 136
147 // If we changed contexts, then we always want to restore it, since the caller 137 // If we changed contexts, then we always want to restore it, since the caller
148 // doesn't know that we're switching contexts. 138 // doesn't know that we're switching contexts.
149 if (scoped_make_current) 139 if (scoped_make_current)
150 mode = kDoRestoreBindings; 140 mode = kDoRestoreBindings;
151 141
152 // Save the current binding if requested. 142 // Save the current binding if requested.
153 GLint bound_service_id = 0; 143 GLint bound_service_id = 0;
154 if (mode == kDoRestoreBindings) 144 if (mode == kDoRestoreBindings)
155 glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &bound_service_id); 145 glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &bound_service_id);
156 146
157 surface_texture_->UpdateTexImage(); 147 surface_texture_->UpdateTexImage();
158 if (mode == kDoRestoreBindings) 148 if (mode == kDoRestoreBindings)
159 glBindTexture(GL_TEXTURE_EXTERNAL_OES, bound_service_id); 149 glBindTexture(GL_TEXTURE_EXTERNAL_OES, bound_service_id);
160 150
161 // Helpfully, this is already column major. 151 // Helpfully, this is already column major.
162 surface_texture_->GetTransformMatrix(gl_matrix_); 152 surface_texture_->GetTransformMatrix(gl_matrix_);
163 } 153 }
164 154
165 void AVDACodecImage::SetMediaCodecBufferIndex(int buffer_index) { 155 void AVDACodecImage::SetMediaCodecBufferIndex(int buffer_index) {
166 codec_buffer_index_ = buffer_index; 156 codec_buffer_index_ = buffer_index;
167 } 157 }
168 158
169 int AVDACodecImage::GetMediaCodecBufferIndex() const {
170 return codec_buffer_index_;
171 }
172
173 void AVDACodecImage::SetSize(const gfx::Size& size) { 159 void AVDACodecImage::SetSize(const gfx::Size& size) {
174 size_ = size; 160 size_ = size;
175 } 161 }
176 162
163 void AVDACodecImage::ReleaseOutputBuffer(ReleaseMode release_mode) {
164 if (!IsCodecBufferOutstanding())
165 return;
166
167 DCHECK_NE(codec_buffer_index_, kInvalidCodecBufferIndex);
168
169 if (release_mode == ReleaseMode::SKIP_RENDER) {
170 if (codec_buffer_index_ != kUpdateOnly)
171 media_codec_->ReleaseOutputBuffer(codec_buffer_index_, false);
172 codec_buffer_index_ = kInvalidCodecBufferIndex;
173 return;
174 }
175
176 if (release_mode == ReleaseMode::RENDER_ONLY) {
liberato (no reviews please) 2016/04/22 00:51:06 DCHECK(surface_texture_)
DaleCurtis 2016/04/22 01:33:58 Done.
177 if (codec_buffer_index_ == kUpdateOnly)
178 return;
179
180 media_codec_->ReleaseOutputBuffer(codec_buffer_index_, true);
181 codec_buffer_index_ = kUpdateOnly;
182
183 // This must be synchronous, so wait for OnFrameAvailable.
184 SCOPED_UMA_HISTOGRAM_TIMER("Media.AvdaCodecImage.WaitTimeForFrame");
185 shared_state_->WaitForFrameAvailable();
186 return;
187 }
188
189 DCHECK(release_mode == ReleaseMode::RENDER_AND_UPDATE);
190
191 if (!surface_texture_) {
192 DCHECK_NE(codec_buffer_index_, kUpdateOnly);
193 media_codec_->ReleaseOutputBuffer(codec_buffer_index_, true);
194 codec_buffer_index_ = kInvalidCodecBufferIndex;
195 return;
196 }
197
198 // Surface texture is already attached, so just update it.
199 if (shared_state_->surface_texture_is_attached()) {
200 // Warning: This will cause reentrancy to this function.
201 UpdateSurfaceTexture(kDoRestoreBindings);
liberato (no reviews please) 2016/04/22 00:51:06 i think that this can be simplified to avoid the m
DaleCurtis 2016/04/22 01:33:58 I agree the recursion is nasty, will think on it s
liberato (no reviews please) 2016/04/22 02:16:43 the public api would be UpdateSurface(). i agree
202 return;
203 }
204
205 // Don't attach the surface texture permanently. Perhaps we should just
206 // attach the surface texture in avda and be done with it.
207 GLuint service_id = 0;
208 glGenTextures(1, &service_id);
209 GLint bound_service_id = 0;
210 glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &bound_service_id);
211 glBindTexture(GL_TEXTURE_EXTERNAL_OES, service_id);
212 AttachSurfaceTextureToContext();
213
214 // Warning: This will cause reentrancy to this function.
215 UpdateSurfaceTexture(kDontRestoreBindings);
216
217 // Detach the surface texture, which deletes the generated texture.
218 surface_texture_->DetachFromGLContext();
219 shared_state_->DidDetachSurfaceTexture();
220 glBindTexture(GL_TEXTURE_EXTERNAL_OES, bound_service_id);
221 }
222
177 void AVDACodecImage::SetMediaCodec(media::MediaCodecBridge* codec) { 223 void AVDACodecImage::SetMediaCodec(media::MediaCodecBridge* codec) {
178 media_codec_ = codec; 224 media_codec_ = codec;
179 codec_buffer_index_ = -1; 225 codec_buffer_index_ = kInvalidCodecBufferIndex;
180 } 226 }
181 227
182 void AVDACodecImage::SetTexture(gpu::gles2::Texture* texture) { 228 void AVDACodecImage::SetTexture(gpu::gles2::Texture* texture) {
183 texture_ = texture; 229 texture_ = texture;
184 } 230 }
185 231
186 void AVDACodecImage::AttachSurfaceTextureToContext() { 232 void AVDACodecImage::AttachSurfaceTextureToContext() {
187 DCHECK(surface_texture_); 233 DCHECK(surface_texture_);
188 234
189 // We assume that the currently bound texture is the intended one. 235 // We assume that the currently bound texture is the intended one.
(...skipping 17 matching lines...) Expand all
207 std::unique_ptr<ui::ScopedMakeCurrent> scoped_make_current; 253 std::unique_ptr<ui::ScopedMakeCurrent> scoped_make_current;
208 if (!shared_state_->context()->IsCurrent(NULL)) { 254 if (!shared_state_->context()->IsCurrent(NULL)) {
209 scoped_make_current.reset(new ui::ScopedMakeCurrent( 255 scoped_make_current.reset(new ui::ScopedMakeCurrent(
210 shared_state_->context(), shared_state_->surface())); 256 shared_state_->context(), shared_state_->surface()));
211 } 257 }
212 258
213 return scoped_make_current; 259 return scoped_make_current;
214 } 260 }
215 261
216 void AVDACodecImage::GetTextureMatrix(float matrix[16]) { 262 void AVDACodecImage::GetTextureMatrix(float matrix[16]) {
217 if (IsCodecBufferOutstanding() && shared_state_ && surface_texture_) { 263 // Our current matrix may be stale. Update it if possible.
218 // Our current matrix may be stale. Update it if possible. 264 ReleaseOutputBuffer(ReleaseMode::RENDER_AND_UPDATE);
liberato (no reviews please) 2016/04/22 00:51:06 this eats the check for |surface_texture_|. shoul
DaleCurtis 2016/04/22 01:33:58 Done.
219 if (!shared_state_->surface_texture_is_attached()) {
220 // Don't attach the surface texture permanently. Perhaps we should
221 // just attach the surface texture in avda and be done with it.
222 GLuint service_id = 0;
223 glGenTextures(1, &service_id);
224 GLint bound_service_id = 0;
225 glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &bound_service_id);
226 glBindTexture(GL_TEXTURE_EXTERNAL_OES, service_id);
227 AttachSurfaceTextureToContext();
228 UpdateSurfaceTexture(kDontRestoreBindings);
229 // Detach the surface texture, which deletes the generated texture.
230 surface_texture_->DetachFromGLContext();
231 shared_state_->DidDetachSurfaceTexture();
232 glBindTexture(GL_TEXTURE_EXTERNAL_OES, bound_service_id);
233 } else {
234 // Surface texture is already attached, so just update it.
235 UpdateSurfaceTexture(kDoRestoreBindings);
236 }
237 }
238
239 memcpy(matrix, gl_matrix_, sizeof(gl_matrix_)); 265 memcpy(matrix, gl_matrix_, sizeof(gl_matrix_));
240 } 266 }
241 267
242 bool AVDACodecImage::IsCodecBufferOutstanding() const { 268 bool AVDACodecImage::IsCodecBufferOutstanding() const {
243 return codec_buffer_index_ != kInvalidCodecBufferIndex && media_codec_; 269 return codec_buffer_index_ != kInvalidCodecBufferIndex && media_codec_;
244 } 270 }
245 271
246 } // namespace content 272 } // namespace content
OLDNEW
« content/common/gpu/media/avda_codec_image.h ('K') | « content/common/gpu/media/avda_codec_image.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698