1/*
2 * Copyright 2020 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef GrD3DTextureResource_DEFINED
9#define GrD3DTextureResource_DEFINED
10
11#include "include/core/SkTypes.h"
12#include "include/gpu/GrBackendSurface.h"
13#include "include/gpu/d3d/GrD3DTypes.h"
14#include "include/private/GrTypesPriv.h"
15#include "src/gpu/GrManagedResource.h"
16#include "src/gpu/d3d/GrD3DResourceState.h"
17
18class GrD3DGpu;
19
20class GrD3DTextureResource : SkNoncopyable {
21private:
22    class Resource;
23
24public:
25    GrD3DTextureResource(const GrD3DTextureResourceInfo& info, sk_sp<GrD3DResourceState> state)
26            : fInfo(info)
27            , fState(std::move(state))
28            , fResource(new Resource(fInfo.fResource, info.fAlloc)) {
29        // gr_cp will implicitly ref the ID3D12Resource for us, so we don't need to worry about
30        // whether it's borrowed or not
31    }
32    virtual ~GrD3DTextureResource();
33
34    ID3D12Resource* d3dResource() const {
35        SkASSERT(fResource);
36        return fInfo.fResource.get();
37    }
38    DXGI_FORMAT dxgiFormat() const { return fInfo.fFormat; }
39    GrBackendFormat getBackendFormat() const {
40        return GrBackendFormat::MakeDxgi(this->dxgiFormat());
41    }
42    sk_sp<Resource> resource() const {
43        SkASSERT(fResource);
44        return fResource;
45    }
46    uint32_t mipLevels() const { return fInfo.fLevelCount; }
47
48    sk_sp<GrD3DResourceState> grD3DResourceState() const { return fState; }
49
50    D3D12_RESOURCE_STATES currentState() const {
51        return fState->getResourceState();
52    }
53
54    void setResourceState(const GrD3DGpu* gpu, D3D12_RESOURCE_STATES newResourceState,
55                          unsigned int subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES);
56
57    // Changes the layout to present
58    void prepareForPresent(GrD3DGpu* gpu);
59
60    unsigned int sampleQualityPattern() const { return fInfo.fSampleQualityPattern; }
61
62    // This simply updates our tracking of the resourceState and does not actually do any gpu work.
63    // Externally, primarily used for implicit changes in resourceState due to certain GPU commands.
64    void updateResourceState(D3D12_RESOURCE_STATES newState) {
65        SkASSERT(fResource);
66        fState->setResourceState(newState);
67    }
68
69    static bool InitTextureResourceInfo(GrD3DGpu* gpu, const D3D12_RESOURCE_DESC& desc,
70                                        D3D12_RESOURCE_STATES initialState, GrProtected,
71                                        D3D12_CLEAR_VALUE*, GrD3DTextureResourceInfo*);
72    static std::pair<GrD3DTextureResourceInfo, sk_sp<GrD3DResourceState>> CreateMSAA(
73            GrD3DGpu* gpu, SkISize dimensions, int sampleCnt, const GrD3DTextureResourceInfo& info,
74            SkColor4f clearColor);
75
76    void setResourceRelease(sk_sp<GrRefCntedCallback> releaseHelper);
77
78protected:
79    void releaseResource(GrD3DGpu* gpu);
80
81    GrD3DTextureResourceInfo fInfo;
82    sk_sp<GrD3DResourceState> fState;
83
84private:
85    class Resource : public GrTextureResource {
86    public:
87        explicit Resource()
88            : fResource(nullptr)
89            , fAlloc(nullptr) {
90        }
91
92        Resource(const gr_cp<ID3D12Resource>& textureResource,
93                 const sk_sp<GrD3DAlloc>& alloc)
94            : fResource(textureResource)
95            , fAlloc(alloc) {
96        }
97
98        ~Resource() override {}
99
100#ifdef SK_TRACE_MANAGED_RESOURCES
101        void dumpInfo() const override {
102            SkDebugf("GrD3DTextureResource: %p (%d refs)\n", fResource.get(), this->getRefCnt());
103        }
104#endif
105
106    private:
107        void freeGPUData() const override;
108
109        mutable gr_cp<ID3D12Resource> fResource;
110        mutable sk_sp<GrD3DAlloc> fAlloc;
111
112        using INHERITED = GrTextureResource;
113    };
114
115    sk_sp<Resource> fResource;
116
117    friend class GrD3DRenderTarget;
118};
119
120#endif
121