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

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

Issue 2351293003: Relocate SurfaceTexture usage from AVDA GLImage into shared state. (Closed)
Patch Set: Unflip default matrix. Created 4 years, 2 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 "media/gpu/avda_codec_image.h" 5 #include "media/gpu/avda_codec_image.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 8
9 #include <memory> 9 #include <memory>
10 10
11 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" 11 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
12 #include "gpu/command_buffer/service/texture_manager.h" 12 #include "gpu/command_buffer/service/texture_manager.h"
13 #include "media/base/android/sdk_media_codec_bridge.h" 13 #include "media/base/android/sdk_media_codec_bridge.h"
14 #include "media/gpu/avda_shared_state.h" 14 #include "media/gpu/avda_shared_state.h"
15 #include "ui/gl/android/surface_texture.h" 15 #include "ui/gl/android/surface_texture.h"
16 #include "ui/gl/gl_context.h" 16 #include "ui/gl/gl_context.h"
17 #include "ui/gl/scoped_make_current.h" 17 #include "ui/gl/scoped_make_current.h"
18 18
19 namespace media { 19 namespace media {
20 20
21 AVDACodecImage::AVDACodecImage( 21 AVDACodecImage::AVDACodecImage(
22 int picture_buffer_id, 22 int picture_buffer_id,
23 const scoped_refptr<AVDASharedState>& shared_state, 23 const scoped_refptr<AVDASharedState>& shared_state,
24 VideoCodecBridge* codec, 24 VideoCodecBridge* codec,
25 const base::WeakPtr<gpu::gles2::GLES2Decoder>& decoder, 25 const base::WeakPtr<gpu::gles2::GLES2Decoder>& decoder)
26 const scoped_refptr<gl::SurfaceTexture>& surface_texture)
27 : shared_state_(shared_state), 26 : shared_state_(shared_state),
28 codec_buffer_index_(kInvalidCodecBufferIndex), 27 codec_buffer_index_(kInvalidCodecBufferIndex),
29 media_codec_(codec), 28 media_codec_(codec),
30 decoder_(decoder), 29 decoder_(decoder),
31 surface_texture_(surface_texture), 30 has_surface_texture_(!!shared_state_->surface_texture_service_id()),
32 texture_(0), 31 texture_(0),
33 picture_buffer_id_(picture_buffer_id) { 32 picture_buffer_id_(picture_buffer_id) {
34 // Default to a sane guess of "flip Y", just in case we can't get
35 // the matrix on the first call.
36 memset(gl_matrix_, 0, sizeof(gl_matrix_));
37 gl_matrix_[0] = gl_matrix_[10] = gl_matrix_[13] = gl_matrix_[15] = 1.0f;
38 gl_matrix_[5] = -1.0f;
39 shared_state_->SetImageForPicture(picture_buffer_id_, this); 33 shared_state_->SetImageForPicture(picture_buffer_id_, this);
40 } 34 }
41 35
42 AVDACodecImage::~AVDACodecImage() { 36 AVDACodecImage::~AVDACodecImage() {
43 shared_state_->SetImageForPicture(picture_buffer_id_, nullptr); 37 shared_state_->SetImageForPicture(picture_buffer_id_, nullptr);
44 } 38 }
45 39
46 void AVDACodecImage::Destroy(bool have_context) {} 40 void AVDACodecImage::Destroy(bool have_context) {}
47 41
48 gfx::Size AVDACodecImage::GetSize() { 42 gfx::Size AVDACodecImage::GetSize() {
49 return size_; 43 return size_;
50 } 44 }
51 45
52 unsigned AVDACodecImage::GetInternalFormat() { 46 unsigned AVDACodecImage::GetInternalFormat() {
53 return GL_RGBA; 47 return GL_RGBA;
54 } 48 }
55 49
56 bool AVDACodecImage::BindTexImage(unsigned target) { 50 bool AVDACodecImage::BindTexImage(unsigned target) {
57 return false; 51 return false;
58 } 52 }
59 53
60 void AVDACodecImage::ReleaseTexImage(unsigned target) {} 54 void AVDACodecImage::ReleaseTexImage(unsigned target) {}
61 55
62 bool AVDACodecImage::CopyTexImage(unsigned target) { 56 bool AVDACodecImage::CopyTexImage(unsigned target) {
63 if (!surface_texture_) 57 if (!has_surface_texture_)
64 return false; 58 return false;
65 59
66 if (target != GL_TEXTURE_EXTERNAL_OES) 60 if (target != GL_TEXTURE_EXTERNAL_OES)
67 return false; 61 return false;
68 62
69 GLint bound_service_id = 0; 63 GLint bound_service_id = 0;
70 glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &bound_service_id); 64 glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &bound_service_id);
71 // We insist that the currently bound texture is the right one. 65 // We insist that the currently bound texture is the right one.
72 if (bound_service_id != 66 if (bound_service_id !=
73 static_cast<GLint>(shared_state_->surface_texture_service_id())) { 67 static_cast<GLint>(shared_state_->surface_texture_service_id())) {
(...skipping 21 matching lines...) Expand all
95 const gfx::Rect& rect) { 89 const gfx::Rect& rect) {
96 return false; 90 return false;
97 } 91 }
98 92
99 bool AVDACodecImage::ScheduleOverlayPlane(gfx::AcceleratedWidget widget, 93 bool AVDACodecImage::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
100 int z_order, 94 int z_order,
101 gfx::OverlayTransform transform, 95 gfx::OverlayTransform transform,
102 const gfx::Rect& bounds_rect, 96 const gfx::Rect& bounds_rect,
103 const gfx::RectF& crop_rect) { 97 const gfx::RectF& crop_rect) {
104 // This should only be called when we're rendering to a SurfaceView. 98 // This should only be called when we're rendering to a SurfaceView.
105 if (surface_texture_) { 99 if (has_surface_texture_) {
106 DVLOG(1) << "Invalid call to ScheduleOverlayPlane; this image is " 100 DVLOG(1) << "Invalid call to ScheduleOverlayPlane; this image is "
107 "SurfaceTexture backed."; 101 "SurfaceTexture backed.";
108 return false; 102 return false;
109 } 103 }
110 104
111 UpdateSurface(UpdateMode::RENDER_TO_FRONT_BUFFER); 105 UpdateSurface(UpdateMode::RENDER_TO_FRONT_BUFFER);
112 return true; 106 return true;
113 } 107 }
114 108
115 void AVDACodecImage::OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd, 109 void AVDACodecImage::OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
116 uint64_t process_tracing_id, 110 uint64_t process_tracing_id,
117 const std::string& dump_name) {} 111 const std::string& dump_name) {}
118 112
119 void AVDACodecImage::UpdateSurfaceTexture(RestoreBindingsMode mode) { 113 void AVDACodecImage::UpdateSurfaceTexture(RestoreBindingsMode mode) {
120 DCHECK(surface_texture_); 114 DCHECK(has_surface_texture_);
121 DCHECK_EQ(codec_buffer_index_, kUpdateOnly); 115 DCHECK_EQ(codec_buffer_index_, kUpdateOnly);
122 codec_buffer_index_ = kRendered; 116 codec_buffer_index_ = kRendered;
123 117
124 // Swap the rendered image to the front. 118 // Swap the rendered image to the front.
125 std::unique_ptr<ui::ScopedMakeCurrent> scoped_make_current = 119 std::unique_ptr<ui::ScopedMakeCurrent> scoped_make_current =
126 MakeCurrentIfNeeded(); 120 MakeCurrentIfNeeded();
127 121
128 // If we changed contexts, then we always want to restore it, since the caller 122 // If we changed contexts, then we always want to restore it, since the caller
129 // doesn't know that we're switching contexts. 123 // doesn't know that we're switching contexts.
130 if (scoped_make_current) 124 if (scoped_make_current)
131 mode = kDoRestoreBindings; 125 mode = kDoRestoreBindings;
132 126
133 // Save the current binding if requested. 127 // Save the current binding if requested.
134 GLint bound_service_id = 0; 128 GLint bound_service_id = 0;
135 if (mode == kDoRestoreBindings) 129 if (mode == kDoRestoreBindings)
136 glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &bound_service_id); 130 glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &bound_service_id);
137 131
138 surface_texture_->UpdateTexImage(); 132 shared_state_->UpdateTexImage();
139 if (mode == kDoRestoreBindings) 133 if (mode == kDoRestoreBindings)
140 glBindTexture(GL_TEXTURE_EXTERNAL_OES, bound_service_id); 134 glBindTexture(GL_TEXTURE_EXTERNAL_OES, bound_service_id);
141
142 // Helpfully, this is already column major.
143 surface_texture_->GetTransformMatrix(gl_matrix_);
144 } 135 }
145 136
146 void AVDACodecImage::UpdateSurface(UpdateMode update_mode) { 137 void AVDACodecImage::UpdateSurface(UpdateMode update_mode) {
147 UpdateSurfaceInternal(update_mode, kDoRestoreBindings); 138 UpdateSurfaceInternal(update_mode, kDoRestoreBindings);
148 } 139 }
149 140
150 void AVDACodecImage::CodecChanged(MediaCodecBridge* codec) { 141 void AVDACodecImage::CodecChanged(MediaCodecBridge* codec) {
151 media_codec_ = codec; 142 media_codec_ = codec;
152 codec_buffer_index_ = kInvalidCodecBufferIndex; 143 codec_buffer_index_ = kInvalidCodecBufferIndex;
153 } 144 }
154 145
155 void AVDACodecImage::UpdateSurfaceInternal( 146 void AVDACodecImage::UpdateSurfaceInternal(
156 UpdateMode update_mode, 147 UpdateMode update_mode,
157 RestoreBindingsMode attached_bindings_mode) { 148 RestoreBindingsMode attached_bindings_mode) {
158 if (!IsCodecBufferOutstanding()) 149 if (!IsCodecBufferOutstanding())
159 return; 150 return;
160 151
161 ReleaseOutputBuffer(update_mode); 152 ReleaseOutputBuffer(update_mode);
162 153
163 // SurfaceViews are updated implicitly, so no further steps are necessary. 154 // SurfaceViews are updated implicitly, so no further steps are necessary.
164 if (!surface_texture_) { 155 if (!has_surface_texture_) {
165 DCHECK(update_mode != UpdateMode::RENDER_TO_BACK_BUFFER); 156 DCHECK(update_mode != UpdateMode::RENDER_TO_BACK_BUFFER);
166 return; 157 return;
167 } 158 }
168 159
169 // If front buffer rendering hasn't been requested, exit early. 160 // If front buffer rendering hasn't been requested, exit early.
170 if (update_mode != UpdateMode::RENDER_TO_FRONT_BUFFER) 161 if (update_mode != UpdateMode::RENDER_TO_FRONT_BUFFER)
171 return; 162 return;
172 163
173 UpdateSurfaceTexture(attached_bindings_mode); 164 UpdateSurfaceTexture(attached_bindings_mode);
174 } 165 }
175 166
176 void AVDACodecImage::ReleaseOutputBuffer(UpdateMode update_mode) { 167 void AVDACodecImage::ReleaseOutputBuffer(UpdateMode update_mode) {
177 DCHECK(IsCodecBufferOutstanding()); 168 DCHECK(IsCodecBufferOutstanding());
178 169
179 // In case of discard, simply discard and clear our codec buffer index. 170 // In case of discard, simply discard and clear our codec buffer index.
180 if (update_mode == UpdateMode::DISCARD_CODEC_BUFFER) { 171 if (update_mode == UpdateMode::DISCARD_CODEC_BUFFER) {
181 if (codec_buffer_index_ != kUpdateOnly) 172 if (codec_buffer_index_ != kUpdateOnly)
182 media_codec_->ReleaseOutputBuffer(codec_buffer_index_, false); 173 media_codec_->ReleaseOutputBuffer(codec_buffer_index_, false);
183 174
184 // Note: No need to wait for the frame to be available in the kUpdateOnly 175 // Note: No need to wait for the frame to be available in the kUpdateOnly
185 // case since it will be or has been waited on by another release call. 176 // case since it will be or has been waited on by another release call.
186 codec_buffer_index_ = kInvalidCodecBufferIndex; 177 codec_buffer_index_ = kInvalidCodecBufferIndex;
187 return; 178 return;
188 } 179 }
189 180
190 DCHECK(update_mode == UpdateMode::RENDER_TO_BACK_BUFFER || 181 DCHECK(update_mode == UpdateMode::RENDER_TO_BACK_BUFFER ||
191 update_mode == UpdateMode::RENDER_TO_FRONT_BUFFER); 182 update_mode == UpdateMode::RENDER_TO_FRONT_BUFFER);
192 183
193 if (!surface_texture_) { 184 if (!has_surface_texture_) {
194 DCHECK(update_mode == UpdateMode::RENDER_TO_FRONT_BUFFER); 185 DCHECK(update_mode == UpdateMode::RENDER_TO_FRONT_BUFFER);
195 DCHECK_GE(codec_buffer_index_, 0); 186 DCHECK_GE(codec_buffer_index_, 0);
196 media_codec_->ReleaseOutputBuffer(codec_buffer_index_, true); 187 media_codec_->ReleaseOutputBuffer(codec_buffer_index_, true);
197 codec_buffer_index_ = kRendered; 188 codec_buffer_index_ = kRendered;
198 return; 189 return;
199 } 190 }
200 191
201 // If we've already released to the back buffer, there's nothing left to do, 192 // If we've already released to the back buffer, there's nothing left to do,
202 // but wait for the previously released buffer if necessary. 193 // but wait for the previously released buffer if necessary.
203 if (codec_buffer_index_ != kUpdateOnly) { 194 if (codec_buffer_index_ != kUpdateOnly) {
204 DCHECK(surface_texture_); 195 DCHECK(has_surface_texture_);
205 DCHECK_GE(codec_buffer_index_, 0); 196 DCHECK_GE(codec_buffer_index_, 0);
206 shared_state_->RenderCodecBufferToSurfaceTexture(media_codec_, 197 shared_state_->RenderCodecBufferToSurfaceTexture(media_codec_,
207 codec_buffer_index_); 198 codec_buffer_index_);
208 codec_buffer_index_ = kUpdateOnly; 199 codec_buffer_index_ = kUpdateOnly;
209 } 200 }
210 201
211 // Only wait for the SurfaceTexture update if we're rendering to the front. 202 // Only wait for the SurfaceTexture update if we're rendering to the front.
212 if (update_mode == UpdateMode::RENDER_TO_FRONT_BUFFER) 203 if (update_mode == UpdateMode::RENDER_TO_FRONT_BUFFER)
213 shared_state_->WaitForFrameAvailable(); 204 shared_state_->WaitForFrameAvailable();
214 } 205 }
215 206
216 std::unique_ptr<ui::ScopedMakeCurrent> AVDACodecImage::MakeCurrentIfNeeded() { 207 std::unique_ptr<ui::ScopedMakeCurrent> AVDACodecImage::MakeCurrentIfNeeded() {
217 DCHECK(shared_state_->context()); 208 DCHECK(shared_state_->context());
218 std::unique_ptr<ui::ScopedMakeCurrent> scoped_make_current; 209 std::unique_ptr<ui::ScopedMakeCurrent> scoped_make_current;
219 // Remember: virtual contexts return true if and only if their shared context 210 // Remember: virtual contexts return true if and only if their shared context
220 // is current, regardless of which virtual context it is. 211 // is current, regardless of which virtual context it is.
221 if (!shared_state_->context()->IsCurrent(NULL)) { 212 if (!shared_state_->context()->IsCurrent(NULL)) {
222 scoped_make_current.reset(new ui::ScopedMakeCurrent( 213 scoped_make_current.reset(new ui::ScopedMakeCurrent(
223 shared_state_->context(), shared_state_->surface())); 214 shared_state_->context(), shared_state_->surface()));
224 } 215 }
225 216
226 return scoped_make_current; 217 return scoped_make_current;
227 } 218 }
228 219
229 void AVDACodecImage::GetTextureMatrix(float matrix[16]) { 220 void AVDACodecImage::GetTextureMatrix(float matrix[16]) {
230 // Our current matrix may be stale. Update it if possible. 221 // Our current matrix may be stale. Update it if possible.
231 if (surface_texture_) 222 if (has_surface_texture_)
232 UpdateSurface(UpdateMode::RENDER_TO_FRONT_BUFFER); 223 UpdateSurface(UpdateMode::RENDER_TO_FRONT_BUFFER);
233 memcpy(matrix, gl_matrix_, sizeof(gl_matrix_)); 224 shared_state_->GetTransformMatrix(matrix);
234 YInvertMatrix(matrix); 225 YInvertMatrix(matrix);
235 } 226 }
236 227
237 bool AVDACodecImage::IsCodecBufferOutstanding() const { 228 bool AVDACodecImage::IsCodecBufferOutstanding() const {
238 static_assert(kUpdateOnly < 0 && kUpdateOnly > kRendered && 229 static_assert(kUpdateOnly < 0 && kUpdateOnly > kRendered &&
239 kRendered > kInvalidCodecBufferIndex, 230 kRendered > kInvalidCodecBufferIndex,
240 "Codec buffer index enum values are not ordered correctly."); 231 "Codec buffer index enum values are not ordered correctly.");
241 return codec_buffer_index_ > kRendered && media_codec_; 232 return codec_buffer_index_ > kRendered && media_codec_;
242 } 233 }
243 234
244 } // namespace media 235 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698