Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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/dxva_video_decode_accelerator.h" | 5 #include "content/common/gpu/media/dxva_video_decode_accelerator.h" |
| 6 | 6 |
| 7 #if !defined(OS_WIN) | 7 #if !defined(OS_WIN) |
| 8 #error This file should only be built on Windows. | 8 #error This file should only be built on Windows. |
| 9 #endif // !defined(OS_WIN) | 9 #endif // !defined(OS_WIN) |
| 10 | 10 |
| (...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 377 glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture); | 377 glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture); |
| 378 | 378 |
| 379 glBindTexture(GL_TEXTURE_2D, picture_buffer_.texture_id()); | 379 glBindTexture(GL_TEXTURE_2D, picture_buffer_.texture_id()); |
| 380 | 380 |
| 381 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 381 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| 382 | 382 |
| 383 if (device_supports_format_conversion) { | 383 if (device_supports_format_conversion) { |
| 384 base::win::ScopedComPtr<IDirect3DSurface9> d3d_surface; | 384 base::win::ScopedComPtr<IDirect3DSurface9> d3d_surface; |
| 385 HRESULT hr = decoding_texture_->GetSurfaceLevel(0, d3d_surface.Receive()); | 385 HRESULT hr = decoding_texture_->GetSurfaceLevel(0, d3d_surface.Receive()); |
| 386 RETURN_ON_HR_FAILURE(hr, "Failed to get surface from texture", false); | 386 RETURN_ON_HR_FAILURE(hr, "Failed to get surface from texture", false); |
| 387 | |
| 388 // Ideally, this should be done immediately before the draw call that uses | |
| 389 // the texture. Flush it once here though. | |
| 390 hr = query_->Issue(D3DISSUE_END); | |
|
ananta
2012/11/14 03:06:48
Issuing the query upfront causes the loop below to
| |
| 391 RETURN_ON_HR_FAILURE(hr, "Failed to issue END", false); | |
| 392 | |
| 393 // The BeginScene/EndScene calls below indicate the start/end of rendering. | |
| 394 // It is an effort to ensure that pending rendering operations are flushed. | |
| 395 hr = device_->BeginScene(); | |
| 396 RETURN_ON_HR_FAILURE(hr, "BeginScene failed", false); | |
| 387 | 397 |
| 388 hr = device_->StretchRect(dest_surface, | 398 hr = device_->StretchRect(dest_surface, |
| 389 NULL, | 399 NULL, |
| 390 d3d_surface, | 400 d3d_surface, |
| 391 NULL, | 401 NULL, |
| 392 D3DTEXF_NONE); | 402 D3DTEXF_NONE); |
| 393 RETURN_ON_HR_FAILURE(hr, "Colorspace conversion via StretchRect failed", | 403 RETURN_ON_HR_FAILURE(hr, "Colorspace conversion via StretchRect failed", |
| 394 false); | 404 false); |
| 395 // Ideally, this should be done immediately before the draw call that uses | 405 |
| 396 // the texture. Flush it once here though. | 406 hr = device_->EndScene(); |
| 397 hr = query_->Issue(D3DISSUE_END); | 407 RETURN_ON_HR_FAILURE(hr, "EndScene failed", false); |
| 398 RETURN_ON_HR_FAILURE(hr, "Failed to issue END", false); | 408 |
| 399 do { | 409 // The DXVA decoder has its own device which it uses for decoding. ANGLE |
| 400 hr = query_->GetData(NULL, 0, D3DGETDATA_FLUSH); | 410 // has its own device which we don't have access to. |
| 401 if (hr == S_FALSE) | 411 // The above code attempts to copy the decoded picture into a surface |
| 402 Sleep(1); // Poor-man's Yield(). | 412 // which is owned by ANGLE. As there are multiple devices involved in |
| 403 } while (hr == S_FALSE); | 413 // this, the StretchRect call above is not synchronous. |
| 414 // We attempt to flush the batched operations to ensure that the picture is | |
| 415 // copied to the surface owned by ANGLE. | |
| 416 // We need to do this in a loop and call flush multiple times. | |
| 417 while (query_->GetData(NULL, 0, D3DGETDATA_FLUSH) == S_FALSE) { | |
| 418 Sleep(1); // Poor-man's Yield(). | |
| 419 } | |
| 404 eglBindTexImage( | 420 eglBindTexImage( |
| 405 static_cast<EGLDisplay*>(eglGetDisplay(EGL_DEFAULT_DISPLAY)), | 421 static_cast<EGLDisplay*>(eglGetDisplay(EGL_DEFAULT_DISPLAY)), |
| 406 decoding_surface_, | 422 decoding_surface_, |
| 407 EGL_BACK_BUFFER); | 423 EGL_BACK_BUFFER); |
| 408 } else { | 424 } else { |
| 409 scoped_array<char> bits; | 425 scoped_array<char> bits; |
| 410 RETURN_ON_FAILURE(GetBitmapFromSurface(DXVAVideoDecodeAccelerator::device_, | 426 RETURN_ON_FAILURE(GetBitmapFromSurface(DXVAVideoDecodeAccelerator::device_, |
| 411 dest_surface, &bits), | 427 dest_surface, &bits), |
| 412 "Failed to get bitmap from surface for rendering", | 428 "Failed to get bitmap from surface for rendering", |
| 413 false); | 429 false); |
| (...skipping 724 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1138 return; | 1154 return; |
| 1139 } | 1155 } |
| 1140 | 1156 |
| 1141 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | 1157 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( |
| 1142 &DXVAVideoDecodeAccelerator::NotifyFlushDone, base::AsWeakPtr(this))); | 1158 &DXVAVideoDecodeAccelerator::NotifyFlushDone, base::AsWeakPtr(this))); |
| 1143 | 1159 |
| 1144 state_ = kNormal; | 1160 state_ = kNormal; |
| 1145 } | 1161 } |
| 1146 | 1162 |
| 1147 } // namespace content | 1163 } // namespace content |
| OLD | NEW |