OLD | NEW |
---|---|
1 // Copyright 2011 The Chromium Authors. All rights reserved. | 1 // Copyright 2011 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 "config.h" | 5 #include "config.h" |
6 | 6 |
7 #include "cc/video_layer_impl.h" | 7 #include "cc/video_layer_impl.h" |
8 | 8 |
9 #include "NotImplemented.h" | 9 #include "NotImplemented.h" |
10 #include "cc/io_surface_draw_quad.h" | 10 #include "cc/io_surface_draw_quad.h" |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
115 if (!m_provider) { | 115 if (!m_provider) { |
116 m_frame = 0; | 116 m_frame = 0; |
117 return; | 117 return; |
118 } | 118 } |
119 | 119 |
120 m_frame = m_provider->getCurrentFrame(); | 120 m_frame = m_provider->getCurrentFrame(); |
121 | 121 |
122 if (!m_frame) | 122 if (!m_frame) |
123 return; | 123 return; |
124 | 124 |
125 // If these fail, we'll have to add draw logic that handles offset bitmap/ | |
126 // texture UVs. For now, just expect (0, 0) offset. | |
Ami GONE FROM CHROMIUM
2012/10/25 17:13:34
IIUC you're saying none of the downstream creators
sheu
2012/10/25 21:44:13
Yep, everything generates 0,0 so far. Updating co
| |
127 DCHECK_EQ(m_frame->visibleRect().x, 0); | |
128 DCHECK_EQ(m_frame->visibleRect().y, 0); | |
129 | |
125 m_format = convertVFCFormatToGC3DFormat(*m_frame); | 130 m_format = convertVFCFormatToGC3DFormat(*m_frame); |
126 | 131 |
127 if (m_format == GL_INVALID_VALUE) { | 132 if (m_format == GL_INVALID_VALUE) { |
128 m_provider->putCurrentFrame(m_frame); | 133 m_provider->putCurrentFrame(m_frame); |
129 m_frame = 0; | 134 m_frame = 0; |
130 return; | 135 return; |
131 } | 136 } |
132 | 137 |
133 if (m_frame->planes() > WebKit::WebVideoFrame::maxPlanes) { | 138 if (m_frame->planes() > WebKit::WebVideoFrame::maxPlanes) { |
134 m_provider->putCurrentFrame(m_frame); | 139 m_provider->putCurrentFrame(m_frame); |
(...skipping 24 matching lines...) Expand all Loading... | |
159 if (!m_frame) | 164 if (!m_frame) |
160 return; | 165 return; |
161 | 166 |
162 SharedQuadState* sharedQuadState = quadSink.useSharedQuadState(createSharedQ uadState()); | 167 SharedQuadState* sharedQuadState = quadSink.useSharedQuadState(createSharedQ uadState()); |
163 appendDebugBorderQuad(quadSink, sharedQuadState, appendQuadsData); | 168 appendDebugBorderQuad(quadSink, sharedQuadState, appendQuadsData); |
164 | 169 |
165 // FIXME: When we pass quads out of process, we need to double-buffer, or | 170 // FIXME: When we pass quads out of process, we need to double-buffer, or |
166 // otherwise synchonize use of all textures in the quad. | 171 // otherwise synchonize use of all textures in the quad. |
167 | 172 |
168 IntRect quadRect(IntPoint(), contentBounds()); | 173 IntRect quadRect(IntPoint(), contentBounds()); |
174 WebKit::WebRect visibleRect = m_frame->visibleRect(); | |
slavi
2012/10/25 04:44:31
I have a pending CL http://codereview.chromium.org
sheu
2012/10/25 21:44:13
I am lazy and didn't do this :-P. The upstream We
| |
175 WebKit::WebSize textureSize = m_frame->textureSize(); | |
176 | |
177 // pixels for macroblocked formats. | |
178 const float texWidthScale = | |
179 static_cast<float>(visibleRect.width) / textureSize.width; | |
180 const float texHeightScale = | |
181 static_cast<float>(visibleRect.height) / textureSize.height; | |
169 | 182 |
170 switch (m_format) { | 183 switch (m_format) { |
171 case GL_LUMINANCE: { | 184 case GL_LUMINANCE: { |
172 // YUV software decoder. | 185 // YUV software decoder. |
173 const FramePlane& yPlane = m_framePlanes[WebKit::WebVideoFrame::yPlane]; | 186 const FramePlane& yPlane = m_framePlanes[WebKit::WebVideoFrame::yPlane]; |
174 const FramePlane& uPlane = m_framePlanes[WebKit::WebVideoFrame::uPlane]; | 187 const FramePlane& uPlane = m_framePlanes[WebKit::WebVideoFrame::uPlane]; |
175 const FramePlane& vPlane = m_framePlanes[WebKit::WebVideoFrame::vPlane]; | 188 const FramePlane& vPlane = m_framePlanes[WebKit::WebVideoFrame::vPlane]; |
176 scoped_ptr<YUVVideoDrawQuad> yuvVideoQuad = YUVVideoDrawQuad::create(sha redQuadState, quadRect, yPlane, uPlane, vPlane); | 189 FloatSize texScale(texWidthScale, texHeightScale); |
190 scoped_ptr<YUVVideoDrawQuad> yuvVideoQuad = YUVVideoDrawQuad::create( | |
191 sharedQuadState, quadRect, texScale, yPlane, uPlane, vPlane); | |
177 quadSink.append(yuvVideoQuad.PassAs<DrawQuad>(), appendQuadsData); | 192 quadSink.append(yuvVideoQuad.PassAs<DrawQuad>(), appendQuadsData); |
178 break; | 193 break; |
179 } | 194 } |
180 case GL_RGBA: { | 195 case GL_RGBA: { |
181 // RGBA software decoder. | 196 // RGBA software decoder. |
182 const FramePlane& plane = m_framePlanes[WebKit::WebVideoFrame::rgbPlane] ; | 197 const FramePlane& plane = m_framePlanes[WebKit::WebVideoFrame::rgbPlane] ; |
183 float widthScaleFactor = static_cast<float>(plane.visibleSize.width()) / plane.size.width(); | |
184 | |
185 bool premultipliedAlpha = true; | 198 bool premultipliedAlpha = true; |
186 FloatRect uvRect(0, 0, widthScaleFactor, 1); | 199 FloatRect uvRect(0, 0, texWidthScale, texHeightScale); |
187 bool flipped = false; | 200 bool flipped = false; |
188 scoped_ptr<TextureDrawQuad> textureQuad = TextureDrawQuad::create(shared QuadState, quadRect, plane.resourceId, premultipliedAlpha, uvRect, flipped); | 201 scoped_ptr<TextureDrawQuad> textureQuad = TextureDrawQuad::create(shared QuadState, quadRect, plane.resourceId, premultipliedAlpha, uvRect, flipped); |
189 quadSink.append(textureQuad.PassAs<DrawQuad>(), appendQuadsData); | 202 quadSink.append(textureQuad.PassAs<DrawQuad>(), appendQuadsData); |
190 break; | 203 break; |
191 } | 204 } |
192 case GL_TEXTURE_2D: { | 205 case GL_TEXTURE_2D: { |
193 // NativeTexture hardware decoder. | 206 // NativeTexture hardware decoder. |
194 bool premultipliedAlpha = true; | 207 bool premultipliedAlpha = true; |
195 FloatRect uvRect(0, 0, 1, 1); | 208 FloatRect uvRect(0, 0, texWidthScale, texHeightScale); |
196 bool flipped = false; | 209 bool flipped = false; |
197 scoped_ptr<TextureDrawQuad> textureQuad = TextureDrawQuad::create(shared QuadState, quadRect, m_externalTextureResource, premultipliedAlpha, uvRect, flip ped); | 210 scoped_ptr<TextureDrawQuad> textureQuad = TextureDrawQuad::create(shared QuadState, quadRect, m_externalTextureResource, premultipliedAlpha, uvRect, flip ped); |
198 quadSink.append(textureQuad.PassAs<DrawQuad>(), appendQuadsData); | 211 quadSink.append(textureQuad.PassAs<DrawQuad>(), appendQuadsData); |
199 break; | 212 break; |
200 } | 213 } |
201 case GL_TEXTURE_RECTANGLE_ARB: { | 214 case GL_TEXTURE_RECTANGLE_ARB: { |
202 IntSize textureSize(m_frame->width(), m_frame->height()); | 215 IntSize visibleSize(visibleRect.width, visibleRect.height); |
203 scoped_ptr<IOSurfaceDrawQuad> ioSurfaceQuad = IOSurfaceDrawQuad::create( sharedQuadState, quadRect, textureSize, m_frame->textureId(), IOSurfaceDrawQuad: :Unflipped); | 216 scoped_ptr<IOSurfaceDrawQuad> ioSurfaceQuad = IOSurfaceDrawQuad::create( sharedQuadState, quadRect, visibleSize, m_frame->textureId(), IOSurfaceDrawQuad: :Unflipped); |
204 quadSink.append(ioSurfaceQuad.PassAs<DrawQuad>(), appendQuadsData); | 217 quadSink.append(ioSurfaceQuad.PassAs<DrawQuad>(), appendQuadsData); |
205 break; | 218 break; |
206 } | 219 } |
207 case GL_TEXTURE_EXTERNAL_OES: { | 220 case GL_TEXTURE_EXTERNAL_OES: { |
208 // StreamTexture hardware decoder. | 221 // StreamTexture hardware decoder. |
209 scoped_ptr<StreamVideoDrawQuad> streamVideoQuad = StreamVideoDrawQuad::c reate(sharedQuadState, quadRect, m_frame->textureId(), m_streamTextureMatrix); | 222 WebKit::WebTransformationMatrix transform(m_streamTextureMatrix); |
223 transform.scaleNonUniform(texWidthScale, texHeightScale); | |
224 scoped_ptr<StreamVideoDrawQuad> streamVideoQuad = | |
225 StreamVideoDrawQuad::create(sharedQuadState, quadRect, | |
226 m_frame->textureId(), | |
227 m_streamTextureMatrix); | |
210 quadSink.append(streamVideoQuad.PassAs<DrawQuad>(), appendQuadsData); | 228 quadSink.append(streamVideoQuad.PassAs<DrawQuad>(), appendQuadsData); |
211 break; | 229 break; |
212 } | 230 } |
213 default: | 231 default: |
214 CRASH(); // Someone updated convertVFCFormatToGC3DFormat above but updat e this! | 232 CRASH(); // Someone updated convertVFCFormatToGC3DFormat above but updat e this! |
215 } | 233 } |
216 } | 234 } |
217 | 235 |
218 void VideoLayerImpl::didDraw(ResourceProvider* resourceProvider) | 236 void VideoLayerImpl::didDraw(ResourceProvider* resourceProvider) |
219 { | 237 { |
(...skipping 12 matching lines...) Expand all Loading... | |
232 resourceProvider->deleteResource(m_externalTextureResource); | 250 resourceProvider->deleteResource(m_externalTextureResource); |
233 m_externalTextureResource = 0; | 251 m_externalTextureResource = 0; |
234 } | 252 } |
235 | 253 |
236 m_provider->putCurrentFrame(m_frame); | 254 m_provider->putCurrentFrame(m_frame); |
237 m_frame = 0; | 255 m_frame = 0; |
238 | 256 |
239 m_providerLock.Release(); | 257 m_providerLock.Release(); |
240 } | 258 } |
241 | 259 |
242 static int videoFrameDimension(int originalDimension, unsigned plane, int format ) | 260 bool VideoLayerImpl::FramePlane::allocateData( |
243 { | 261 ResourceProvider* resourceProvider) |
244 if (format == WebKit::WebVideoFrame::FormatYV12 && plane != WebKit::WebVideo Frame::yPlane) | |
245 return originalDimension / 2; | |
246 return originalDimension; | |
247 } | |
248 | |
249 static bool hasPaddingBytes(const WebKit::WebVideoFrame& frame, unsigned plane) | |
250 { | |
251 return frame.stride(plane) > videoFrameDimension(frame.width(), plane, frame .format()); | |
252 } | |
253 | |
254 IntSize VideoLayerImpl::computeVisibleSize(const WebKit::WebVideoFrame& frame, u nsigned plane) | |
255 { | |
256 int visibleWidth = videoFrameDimension(frame.width(), plane, frame.format()) ; | |
257 int originalWidth = visibleWidth; | |
258 int visibleHeight = videoFrameDimension(frame.height(), plane, frame.format( )); | |
259 | |
260 // When there are dead pixels at the edge of the texture, decrease | |
261 // the frame width by 1 to prevent the rightmost pixels from | |
262 // interpolating with the dead pixels. | |
263 if (hasPaddingBytes(frame, plane)) | |
264 --visibleWidth; | |
265 | |
266 // In YV12, every 2x2 square of Y values corresponds to one U and | |
267 // one V value. If we decrease the width of the UV plane, we must decrease t he | |
268 // width of the Y texture by 2 for proper alignment. This must happen | |
269 // always, even if Y's texture does not have padding bytes. | |
270 if (plane == WebKit::WebVideoFrame::yPlane && frame.format() == WebKit::WebV ideoFrame::FormatYV12) { | |
271 if (hasPaddingBytes(frame, WebKit::WebVideoFrame::uPlane)) | |
272 visibleWidth = originalWidth - 2; | |
273 } | |
274 | |
275 return IntSize(visibleWidth, visibleHeight); | |
276 } | |
277 | |
278 bool VideoLayerImpl::FramePlane::allocateData(ResourceProvider* resourceProvider ) | |
279 { | 262 { |
280 if (resourceId) | 263 if (resourceId) |
281 return true; | 264 return true; |
282 | 265 |
283 resourceId = resourceProvider->createResource(Renderer::ImplPool, size, form at, ResourceProvider::TextureUsageAny); | 266 resourceId = resourceProvider->createResource(Renderer::ImplPool, size, form at, ResourceProvider::TextureUsageAny); |
284 return resourceId; | 267 return resourceId; |
285 } | 268 } |
286 | 269 |
287 void VideoLayerImpl::FramePlane::freeData(ResourceProvider* resourceProvider) | 270 void VideoLayerImpl::FramePlane::freeData(ResourceProvider* resourceProvider) |
288 { | 271 { |
289 if (!resourceId) | 272 if (!resourceId) |
290 return; | 273 return; |
291 | 274 |
292 resourceProvider->deleteResource(resourceId); | 275 resourceProvider->deleteResource(resourceId); |
293 resourceId = 0; | 276 resourceId = 0; |
294 } | 277 } |
295 | 278 |
296 bool VideoLayerImpl::allocatePlaneData(ResourceProvider* resourceProvider) | 279 bool VideoLayerImpl::allocatePlaneData(ResourceProvider* resourceProvider) |
297 { | 280 { |
281 WebKit::WebSize textureSize = m_frame->textureSize(); | |
298 int maxTextureSize = resourceProvider->maxTextureSize(); | 282 int maxTextureSize = resourceProvider->maxTextureSize(); |
299 for (unsigned planeIndex = 0; planeIndex < m_frame->planes(); ++planeIndex) { | 283 for (unsigned planeIdx = 0; planeIdx < m_frame->planes(); ++planeIdx) { |
300 VideoLayerImpl::FramePlane& plane = m_framePlanes[planeIndex]; | 284 VideoLayerImpl::FramePlane& plane = m_framePlanes[planeIdx]; |
301 | 285 |
302 IntSize requiredTextureSize(m_frame->stride(planeIndex), videoFrameDimen sion(m_frame->height(), planeIndex, m_frame->format())); | 286 IntSize requiredTextureSize(textureSize.width, textureSize.height); |
303 // FIXME: Remove the test against maxTextureSize when tiled layers are i mplemented. | 287 // FIXME: Remove the test against maxTextureSize when tiled layers are |
304 if (requiredTextureSize.isZero() || requiredTextureSize.width() > maxTex tureSize || requiredTextureSize.height() > maxTextureSize) | 288 // implemented. |
289 if (requiredTextureSize.isZero() || | |
290 requiredTextureSize.width() > maxTextureSize || | |
291 requiredTextureSize.height() > maxTextureSize) | |
305 return false; | 292 return false; |
306 | 293 |
307 if (plane.size != requiredTextureSize || plane.format != m_format) { | 294 if (plane.size != requiredTextureSize || plane.format != m_format) { |
308 plane.freeData(resourceProvider); | 295 plane.freeData(resourceProvider); |
309 plane.size = requiredTextureSize; | 296 plane.size = requiredTextureSize; |
310 plane.format = m_format; | 297 plane.format = m_format; |
311 } | 298 } |
312 | 299 |
313 if (!plane.resourceId) { | 300 if (!plane.allocateData(resourceProvider)) |
314 if (!plane.allocateData(resourceProvider)) | 301 return false; |
315 return false; | |
316 plane.visibleSize = computeVisibleSize(*m_frame, planeIndex); | |
317 } | |
318 } | 302 } |
319 return true; | 303 return true; |
320 } | 304 } |
321 | 305 |
322 bool VideoLayerImpl::copyPlaneData(ResourceProvider* resourceProvider) | 306 bool VideoLayerImpl::copyPlaneData(ResourceProvider* resourceProvider) |
323 { | 307 { |
324 size_t softwarePlaneCount = m_frame->planes(); | 308 WebKit::WebSize textureSize = m_frame->textureSize(); |
325 if (!softwarePlaneCount) | 309 for (unsigned planeIdx = 0; planeIdx < m_frame->planes(); ++planeIdx) { |
326 return true; | 310 VideoLayerImpl::FramePlane& plane = m_framePlanes[planeIdx]; |
311 const uint8_t* planePixels = static_cast<const uint8_t*>(m_frame->data(p laneIdx)); | |
327 | 312 |
328 for (size_t softwarePlaneIndex = 0; softwarePlaneIndex < softwarePlaneCount; ++softwarePlaneIndex) { | 313 // Only non-FormatNativeTexture planes should need upload. |
329 VideoLayerImpl::FramePlane& plane = m_framePlanes[softwarePlaneIndex]; | 314 DCHECK_EQ(plane.format, GL_LUMINANCE); |
330 const uint8_t* softwarePlanePixels = static_cast<const uint8_t*>(m_frame ->data(softwarePlaneIndex)); | 315 |
331 IntRect planeRect(IntPoint(), plane.size); | 316 IntRect planeRect(0, 0, plane.size.width(), plane.size.height()); |
332 resourceProvider->upload(plane.resourceId, softwarePlanePixels, planeRec t, planeRect, IntSize()); | 317 IntRect visibleRect(0, 0, textureSize.width, textureSize.height); |
318 resourceProvider->upload(plane.resourceId, planePixels, planeRect, | |
319 visibleRect, IntSize()); | |
333 } | 320 } |
334 return true; | 321 return true; |
335 } | 322 } |
336 | 323 |
337 void VideoLayerImpl::freePlaneData(ResourceProvider* resourceProvider) | 324 void VideoLayerImpl::freePlaneData(ResourceProvider* resourceProvider) |
338 { | 325 { |
339 for (unsigned i = 0; i < WebKit::WebVideoFrame::maxPlanes; ++i) | 326 for (unsigned i = 0; i < WebKit::WebVideoFrame::maxPlanes; ++i) |
340 m_framePlanes[i].freeData(resourceProvider); | 327 m_framePlanes[i].freeData(resourceProvider); |
341 } | 328 } |
342 | 329 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
378 str->append("video layer\n"); | 365 str->append("video layer\n"); |
379 LayerImpl::dumpLayerProperties(str, indent); | 366 LayerImpl::dumpLayerProperties(str, indent); |
380 } | 367 } |
381 | 368 |
382 const char* VideoLayerImpl::layerTypeAsString() const | 369 const char* VideoLayerImpl::layerTypeAsString() const |
383 { | 370 { |
384 return "VideoLayer"; | 371 return "VideoLayer"; |
385 } | 372 } |
386 | 373 |
387 } | 374 } |
OLD | NEW |