1 /*
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "modules/desktop_capture/win/dxgi_texture.h"
12
13 #include <comdef.h>
14 #include <d3d11.h>
15 #include <wrl/client.h>
16
17 #include "modules/desktop_capture/desktop_region.h"
18 #include "rtc_base/checks.h"
19 #include "rtc_base/logging.h"
20
21 using Microsoft::WRL::ComPtr;
22
23 namespace webrtc {
24
25 namespace {
26
27 class DxgiDesktopFrame : public DesktopFrame {
28 public:
DxgiDesktopFrame(const DxgiTexture & texture)29 explicit DxgiDesktopFrame(const DxgiTexture& texture)
30 : DesktopFrame(texture.desktop_size(),
31 texture.pitch(),
32 texture.bits(),
33 nullptr) {}
34
35 ~DxgiDesktopFrame() override = default;
36 };
37
38 } // namespace
39
40 DxgiTexture::DxgiTexture() = default;
41 DxgiTexture::~DxgiTexture() = default;
42
CopyFrom(const DXGI_OUTDUPL_FRAME_INFO & frame_info,IDXGIResource * resource)43 bool DxgiTexture::CopyFrom(const DXGI_OUTDUPL_FRAME_INFO& frame_info,
44 IDXGIResource* resource) {
45 RTC_DCHECK_GT(frame_info.AccumulatedFrames, 0);
46 RTC_DCHECK(resource);
47 ComPtr<ID3D11Texture2D> texture;
48 _com_error error = resource->QueryInterface(
49 __uuidof(ID3D11Texture2D),
50 reinterpret_cast<void**>(texture.GetAddressOf()));
51 if (error.Error() != S_OK || !texture) {
52 RTC_LOG(LS_ERROR) << "Failed to convert IDXGIResource to ID3D11Texture2D, "
53 "error "
54 << error.ErrorMessage() << ", code " << error.Error();
55 return false;
56 }
57
58 D3D11_TEXTURE2D_DESC desc = {0};
59 texture->GetDesc(&desc);
60 desktop_size_.set(desc.Width, desc.Height);
61
62 return CopyFromTexture(frame_info, texture.Get());
63 }
64
AsDesktopFrame()65 const DesktopFrame& DxgiTexture::AsDesktopFrame() {
66 if (!frame_) {
67 frame_.reset(new DxgiDesktopFrame(*this));
68 }
69 return *frame_;
70 }
71
Release()72 bool DxgiTexture::Release() {
73 frame_.reset();
74 return DoRelease();
75 }
76
rect()77 DXGI_MAPPED_RECT* DxgiTexture::rect() {
78 return &rect_;
79 }
80
81 } // namespace webrtc
82