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