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 GrBackendSurfaceMutableState_DEFINED
9 #define GrBackendSurfaceMutableState_DEFINED
10 
11 #include "include/gpu/GrTypes.h"
12 
13 #ifdef SK_VULKAN
14 #include "include/private/GrVkTypesPriv.h"
15 #endif
16 
17 /**
18  * Since Skia and clients can both modify gpu textures and their connected state, Skia needs a way
19  * for clients to inform us if they have modifiend any of this state. In order to not need setters
20  * for every single API and state, we use this class to be a generic wrapper around all the mutable
21  * state. This class is used for calls that inform Skia of these texture/image state changes by the
22  * client as well as for requesting state changes to be done by Skia. The backend specific state
23  * that is wrapped by this class are:
24  *
25  * Vulkan: VkImageLayout and QueueFamilyIndex
26  */
27 class SK_API GrBackendSurfaceMutableState {
28 public:
GrBackendSurfaceMutableState()29     GrBackendSurfaceMutableState() {}
30 
31 #ifdef SK_VULKAN
GrBackendSurfaceMutableState(VkImageLayout layout,uint32_t queueFamilyIndex)32     GrBackendSurfaceMutableState(VkImageLayout layout, uint32_t queueFamilyIndex)
33             : fVkState(layout, queueFamilyIndex)
34             , fBackend(GrBackend::kVulkan)
35             , fIsValid(true) {}
36 #endif
37 
38     GrBackendSurfaceMutableState(const GrBackendSurfaceMutableState& that);
39     GrBackendSurfaceMutableState& operator=(const GrBackendSurfaceMutableState& that);
40 
41 #ifdef SK_VULKAN
42     // If this class is not Vulkan backed it will return value of VK_IMAGE_LAYOUT_UNDEFINED.
43     // Otherwise it will return the VkImageLayout.
getVkImageLayout()44     VkImageLayout getVkImageLayout() const {
45         if (this->isValid() && fBackend != GrBackendApi::kVulkan) {
46             return VK_IMAGE_LAYOUT_UNDEFINED;
47         }
48         return fVkState.getImageLayout();
49     }
50 
51     // If this class is not Vulkan backed it will return value of VK_QUEUE_FAMILY_IGNORED.
52     // Otherwise it will return the VkImageLayout.
getQueueFamilyIndex()53     uint32_t getQueueFamilyIndex() const {
54         if (this->isValid() && fBackend != GrBackendApi::kVulkan) {
55             return VK_QUEUE_FAMILY_IGNORED;
56         }
57         return fVkState.getQueueFamilyIndex();
58     }
59 #endif
60 
61     // Returns true if the backend mutable state has been initialized.
isValid()62     bool isValid() const { return fIsValid; }
63 
backend()64     GrBackendApi backend() const { return fBackend; }
65 
66 private:
67     friend class GrBackendSurfaceMutableStateImpl;
68     friend class GrVkGpu;
69 
70 #ifdef SK_VULKAN
setVulkanState(VkImageLayout layout,uint32_t queueFamilyIndex)71     void setVulkanState(VkImageLayout layout, uint32_t queueFamilyIndex) {
72         SkASSERT(!this->isValid() || fBackend == GrBackendApi::kVulkan);
73         fVkState.setImageLayout(layout);
74         fVkState.setQueueFamilyIndex(queueFamilyIndex);
75         fBackend = GrBackendApi::kVulkan;
76         fIsValid = true;
77     }
78 #endif
79 
80     union {
81         char fDummy;
82 #ifdef SK_VULKAN
83         GrVkSharedImageInfo fVkState;
84 #endif
85     };
86 
87     GrBackend fBackend = GrBackendApi::kMock;
88     bool fIsValid = false;
89 };
90 
91 #endif
92