| Index: ui/gl/gl_image_dxgi.cc | 
| diff --git a/ui/gl/gl_image_dxgi.cc b/ui/gl/gl_image_dxgi.cc | 
| index 2960a6ba10b47463754d811a7935f0e0c7fef599..a470f3305b2b36b53be710cd92dd4e3e997921f6 100644 | 
| --- a/ui/gl/gl_image_dxgi.cc | 
| +++ b/ui/gl/gl_image_dxgi.cc | 
| @@ -31,7 +31,7 @@ unsigned GLImageDXGI::GetInternalFormat() { | 
| } | 
|  | 
| bool GLImageDXGI::BindTexImage(unsigned target) { | 
| -  return false; | 
| +  return true; | 
| } | 
|  | 
| void GLImageDXGI::ReleaseTexImage(unsigned target) {} | 
| @@ -76,4 +76,107 @@ GLImageDXGI::~GLImageDXGI() { | 
| eglDestroyStreamKHR(egl_display, stream_); | 
| } | 
|  | 
| +CopyingGLImageDXGI::CopyingGLImageDXGI( | 
| +    const base::win::ScopedComPtr<ID3D11Device>& d3d11_device, | 
| +    const gfx::Size& size, | 
| +    EGLStreamKHR stream) | 
| +    : GLImageDXGI(size, stream), d3d11_device_(d3d11_device) {} | 
| + | 
| +bool CopyingGLImageDXGI::Initialize() { | 
| +  D3D11_TEXTURE2D_DESC desc; | 
| +  desc.Width = size_.width(); | 
| +  desc.Height = size_.height(); | 
| +  desc.MipLevels = 1; | 
| +  desc.ArraySize = 1; | 
| +  desc.Format = DXGI_FORMAT_NV12; | 
| +  desc.SampleDesc.Count = 1; | 
| +  desc.SampleDesc.Quality = 0; | 
| +  desc.Usage = D3D11_USAGE_DEFAULT; | 
| +  desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; | 
| +  desc.CPUAccessFlags = 0; | 
| +  desc.MiscFlags = 0; | 
| + | 
| +  HRESULT hr = d3d11_device_->CreateTexture2D( | 
| +      &desc, nullptr, decoder_copy_texture_.GetAddressOf()); | 
| +  CHECK(SUCCEEDED(hr)); | 
| +  EGLDisplay egl_display = gl::GLSurfaceEGL::GetHardwareDisplay(); | 
| + | 
| +  EGLAttrib frame_attributes[] = { | 
| +      EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE, 0, EGL_NONE, | 
| +  }; | 
| + | 
| +  EGLBoolean result = eglStreamPostD3DTextureNV12ANGLE( | 
| +      egl_display, stream_, static_cast<void*>(decoder_copy_texture_.Get()), | 
| +      frame_attributes); | 
| +  if (!result) | 
| +    return false; | 
| +  result = eglStreamConsumerAcquireKHR(egl_display, stream_); | 
| +  if (!result) | 
| +    return false; | 
| + | 
| +  d3d11_device_.CopyTo(video_device_.GetAddressOf()); | 
| +  base::win::ScopedComPtr<ID3D11DeviceContext> context; | 
| +  d3d11_device_->GetImmediateContext(context.GetAddressOf()); | 
| +  context.CopyTo(video_context_.GetAddressOf()); | 
| +  return true; | 
| +} | 
| + | 
| +bool CopyingGLImageDXGI::InitializeVideoProcessor( | 
| +    const base::win::ScopedComPtr<ID3D11VideoProcessor>& video_processor, | 
| +    const base::win::ScopedComPtr<ID3D11VideoProcessorEnumerator>& enumerator) { | 
| +  output_view_.Reset(); | 
| + | 
| +  d3d11_processor_ = video_processor; | 
| +  enumerator_ = enumerator; | 
| +  D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC output_view_desc = { | 
| +      D3D11_VPOV_DIMENSION_TEXTURE2D}; | 
| +  output_view_desc.Texture2D.MipSlice = 0; | 
| +  base::win::ScopedComPtr<ID3D11VideoProcessorOutputView> output_view; | 
| +  HRESULT hr = video_device_->CreateVideoProcessorOutputView( | 
| +      decoder_copy_texture_.Get(), enumerator_.Get(), &output_view_desc, | 
| +      output_view_.GetAddressOf()); | 
| +  if (FAILED(hr)) { | 
| +    DLOG(ERROR) << "Failed to get output view"; | 
| +    return false; | 
| +  } | 
| +  return true; | 
| +} | 
| + | 
| +void CopyingGLImageDXGI::UnbindFromTexture() { | 
| +  copied_ = false; | 
| +} | 
| + | 
| +bool CopyingGLImageDXGI::BindTexImage(unsigned target) { | 
| +  if (copied_) | 
| +    return true; | 
| + | 
| +  D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC input_view_desc = {0}; | 
| +  input_view_desc.ViewDimension = D3D11_VPIV_DIMENSION_TEXTURE2D; | 
| +  input_view_desc.Texture2D.ArraySlice = (UINT)level_; | 
| +  input_view_desc.Texture2D.MipSlice = 0; | 
| +  base::win::ScopedComPtr<ID3D11VideoProcessorInputView> input_view; | 
| +  HRESULT hr = video_device_->CreateVideoProcessorInputView( | 
| +      texture_.Get(), enumerator_.Get(), &input_view_desc, | 
| +      input_view.GetAddressOf()); | 
| +  if (FAILED(hr)) { | 
| +    DLOG(ERROR) << "Failed to create video processor input view."; | 
| +    return false; | 
| +  } | 
| + | 
| +  D3D11_VIDEO_PROCESSOR_STREAM streams = {0}; | 
| +  streams.Enable = TRUE; | 
| +  streams.pInputSurface = input_view.Get(); | 
| + | 
| +  hr = video_context_->VideoProcessorBlt(d3d11_processor_.Get(), | 
| +                                         output_view_.Get(), 0, 1, &streams); | 
| +  if (FAILED(hr)) { | 
| +    DLOG(ERROR) << "Failed to process video"; | 
| +    return false; | 
| +  } | 
| +  copied_ = true; | 
| +  return true; | 
| +} | 
| + | 
| +CopyingGLImageDXGI::~CopyingGLImageDXGI() {} | 
| + | 
| }  // namespace gl | 
|  |