Skip to content

Commit 52e16d9

Browse files
egdanielSkia Commit-Bot
authored andcommitted
Update getBackendInfo calls on GrBackendTexture to support VkImageLayout better.
The big api level change here is that the getBackendInfo calls now return by value instead of a pointer. These changes are being made in support of Vulkan so that the client can update the VkImageLayout on the GrBackendTexture and have that update get reflected in our internal tracking of the image. This is done by storing a ref counted GrVkImageLayout object on the GrBackendTexture and the GrVkImage. Bug: skia: Change-Id: I8c6158fd3a66eb61fef97ebf09ea5364bca3f1ae Reviewed-on: https://skia-review.googlesource.com/119101 Reviewed-by: Brian Salomon <[email protected]> Reviewed-by: Robert Phillips <[email protected]> Commit-Queue: Greg Daniel <[email protected]>
1 parent 58627cb commit 52e16d9

29 files changed

+713
-188
lines changed

gn/gpu.gni

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,7 @@ skia_vk_sources = [
523523
"$_include/gpu/vk/GrVkDefines.h",
524524
"$_include/gpu/vk/GrVkInterface.h",
525525
"$_include/gpu/vk/GrVkTypes.h",
526+
"$_include/private/GrVkTypesPriv.h",
526527
"$_src/gpu/vk/GrVkBackendContext.cpp",
527528
"$_src/gpu/vk/GrVkBuffer.cpp",
528529
"$_src/gpu/vk/GrVkBuffer.h",
@@ -552,6 +553,7 @@ skia_vk_sources = [
552553
"$_src/gpu/vk/GrVkGpuCommandBuffer.h",
553554
"$_src/gpu/vk/GrVkImage.cpp",
554555
"$_src/gpu/vk/GrVkImage.h",
556+
"$_src/gpu/vk/GrVkImageLayout.h",
555557
"$_src/gpu/vk/GrVkImageView.cpp",
556558
"$_src/gpu/vk/GrVkImageView.h",
557559
"$_src/gpu/vk/GrVkIndexBuffer.cpp",
@@ -589,6 +591,7 @@ skia_vk_sources = [
589591
"$_src/gpu/vk/GrVkTextureRenderTarget.h",
590592
"$_src/gpu/vk/GrVkTransferBuffer.cpp",
591593
"$_src/gpu/vk/GrVkTransferBuffer.h",
594+
"$_src/gpu/vk/GrVkTypesPriv.cpp",
592595
"$_src/gpu/vk/GrVkUniformBuffer.cpp",
593596
"$_src/gpu/vk/GrVkUniformBuffer.h",
594597
"$_src/gpu/vk/GrVkUniformHandler.cpp",

gn/tests.gni

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ tests_sources = [
274274
"$_tests/UnicodeTest.cpp",
275275
"$_tests/UtilsTest.cpp",
276276
"$_tests/VerticesTest.cpp",
277+
"$_tests/VkBackendSurfaceTest.cpp",
277278
"$_tests/VkHeapTests.cpp",
278279
"$_tests/VkMakeCopyPipelineTest.cpp",
279280
"$_tests/VkUploadPixelsTests.cpp",

include/gpu/GrBackendSurface.h

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414

1515
#ifdef SK_VULKAN
1616
#include "vk/GrVkTypes.h"
17+
#include "../private/GrVkTypesPriv.h"
18+
19+
class GrVkImageLayout;
1720
#endif
1821

1922
#if !SK_SUPPORT_GPU
@@ -136,24 +139,33 @@ class SK_API GrBackendTexture {
136139
GrMipMapped,
137140
const GrMockTextureInfo& mockInfo);
138141

142+
GrBackendTexture(const GrBackendTexture& that);
143+
144+
~GrBackendTexture();
145+
146+
GrBackendTexture& operator=(const GrBackendTexture& that);
147+
139148
int width() const { return fWidth; }
140149
int height() const { return fHeight; }
141150
bool hasMipMaps() const { return GrMipMapped::kYes == fMipMapped; }
142151
GrBackend backend() const {return fBackend; }
143152

144-
// If the backend API is GL, this returns a pointer to the GrGLTextureInfo struct. Otherwise
145-
// it returns nullptr.
146-
const GrGLTextureInfo* getGLTextureInfo() const;
153+
// If the backend API is GL, copies a snapshot of the GrGLTextureInfo struct into the passed in
154+
// pointer and returns true. Otherwise returns false if the backend API is not GL.
155+
bool getGLTextureInfo(GrGLTextureInfo*) const;
147156

148157
#ifdef SK_VULKAN
149-
// If the backend API is Vulkan, this returns a pointer to the GrVkImageInfo struct. Otherwise
150-
// it returns nullptr.
151-
const GrVkImageInfo* getVkImageInfo() const;
158+
// If the backend API is Vulkan, copies a snapshot of the GrGLImageInfo struct into the passed
159+
// in pointer and returns true. This snapshot will set the fImageLayout to the current layout
160+
// state. Otherwise returns false if the backend API is not Vulkan.
161+
bool getVkImageInfo(GrVkImageInfo*) const;
162+
163+
void setVkImageLayout(VkImageLayout);
152164
#endif
153165

154-
// If the backend API is Mock, this returns a pointer to the GrMockTextureInfo struct. Otherwise
155-
// it returns nullptr.
156-
const GrMockTextureInfo* getMockTextureInfo() const;
166+
// If the backend API is Mock, copies a snapshot of the GrMockTextureInfo struct into the passed
167+
// in pointer and returns true. Otherwise returns false if the backend API is not Mock.
168+
bool getMockTextureInfo(GrMockTextureInfo*) const;
157169

158170
// Returns true if the backend texture has been initialized.
159171
bool isValid() const { return fIsValid; }
@@ -182,6 +194,20 @@ class SK_API GrBackendTexture {
182194

183195
GrPixelConfig config() const { return fConfig; }
184196

197+
#ifdef SK_VULKAN
198+
// Requires friending of GrVkGpu (done above already)
199+
sk_sp<GrVkImageLayout> getGrVkImageLayout() const;
200+
201+
friend class GrVkTexture;
202+
GrBackendTexture(int width,
203+
int height,
204+
const GrVkImageInfo& vkInfo,
205+
sk_sp<GrVkImageLayout> layout);
206+
#endif
207+
208+
// Free and release and resources being held by the GrBackendTexture.
209+
void cleanup();
210+
185211
bool fIsValid;
186212
int fWidth; //<! width in pixels
187213
int fHeight; //<! height in pixels
@@ -192,7 +218,7 @@ class SK_API GrBackendTexture {
192218
union {
193219
GrGLTextureInfo fGLInfo;
194220
#ifdef SK_VULKAN
195-
GrVkImageInfo fVkInfo;
221+
GrVkBackendSurfaceInfo fVkInfo;
196222
#endif
197223
GrMockTextureInfo fMockInfo;
198224
};

include/gpu/vk/GrVkTypes.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,22 @@ struct GrVkImageInfo {
7575
VkFormat fFormat;
7676
uint32_t fLevelCount;
7777

78+
GrVkImageInfo()
79+
: fImage(VK_NULL_HANDLE)
80+
, fAlloc()
81+
, fImageTiling(VK_IMAGE_TILING_OPTIMAL)
82+
, fImageLayout(VK_IMAGE_LAYOUT_UNDEFINED)
83+
, fFormat(VK_FORMAT_UNDEFINED)
84+
, fLevelCount(0) {}
85+
86+
GrVkImageInfo(const GrVkImageInfo& info, VkImageLayout layout)
87+
: fImage(info.fImage)
88+
, fAlloc(info.fAlloc)
89+
, fImageTiling(info.fImageTiling)
90+
, fImageLayout(layout)
91+
, fFormat(info.fFormat)
92+
, fLevelCount(info.fLevelCount) {}
93+
7894
// This gives a way for a client to update the layout of the Image if they change the layout
7995
// while we're still holding onto the wrapped texture. They will first need to get a handle
8096
// to our internal GrVkImageInfo by calling getTextureHandle on a GrVkTexture.

include/private/GrVkTypesPriv.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright 2018 Google Inc.
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 GrVkTypesPriv_DEFINED
9+
#define GrVkTypesPriv_DEFINED
10+
11+
#include "GrVkTypes.h"
12+
#include "SkRefCnt.h"
13+
14+
class GrVkImageLayout;
15+
16+
// This struct is to used to store the the actual information about the vulkan backend image on the
17+
// GrBackendTexture and GrBackendRenderTarget. When a client calls getVkImageInfo on a
18+
// GrBackendTexture/RenderTarget, we use the GrVkBackendSurfaceInfo to create a snapshot
19+
// GrVkImgeInfo object. Internally, this uses a ref count GrVkImageLayout object to track the
20+
// current VkImageLayout which can be shared with an internal GrVkImage so that layout updates can
21+
// be seen by all users of the image.
22+
struct GrVkBackendSurfaceInfo {
23+
GrVkBackendSurfaceInfo(GrVkImageInfo info, GrVkImageLayout* layout)
24+
: fImageInfo(info), fLayout(layout) {}
25+
26+
void cleanup();
27+
28+
GrVkBackendSurfaceInfo& operator=(const GrVkBackendSurfaceInfo&) = delete;
29+
30+
// Assigns the passed in GrVkBackendSurfaceInfo to this object. if isValid is true we will also
31+
// attempt to unref the old fLayout on this object.
32+
void assign(const GrVkBackendSurfaceInfo&, bool isValid);
33+
34+
void setImageLayout(VkImageLayout layout);
35+
36+
sk_sp<GrVkImageLayout> getGrVkImageLayout() const;
37+
38+
GrVkImageInfo snapImageInfo() const;
39+
40+
#if GR_TEST_UTILS
41+
bool operator==(const GrVkBackendSurfaceInfo& that) const;
42+
#endif
43+
44+
private:
45+
GrVkImageInfo fImageInfo;
46+
GrVkImageLayout* fLayout;
47+
};
48+
49+
#endif

src/gpu/GrBackendSurface.cpp

Lines changed: 98 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "gl/GrGLUtil.h"
1111

1212
#ifdef SK_VULKAN
13+
#include "vk/GrVkImageLayout.h"
1314
#include "vk/GrVkTypes.h"
1415
#include "vk/GrVkUtil.h"
1516
#endif
@@ -67,13 +68,21 @@ const GrPixelConfig* GrBackendFormat::getMockFormat() const {
6768
GrBackendTexture::GrBackendTexture(int width,
6869
int height,
6970
const GrVkImageInfo& vkInfo)
71+
: GrBackendTexture(width, height, vkInfo,
72+
sk_sp<GrVkImageLayout>(new GrVkImageLayout(vkInfo.fImageLayout))) {}
73+
74+
GrBackendTexture::GrBackendTexture(int width,
75+
int height,
76+
const GrVkImageInfo& vkInfo,
77+
sk_sp<GrVkImageLayout> layout)
7078
: fIsValid(true)
7179
, fWidth(width)
7280
, fHeight(height)
7381
, fConfig(GrVkFormatToPixelConfig(vkInfo.fFormat))
7482
, fMipMapped(GrMipMapped(vkInfo.fLevelCount > 1))
7583
, fBackend(kVulkan_GrBackend)
76-
, fVkInfo(vkInfo) {}
84+
, fVkInfo(vkInfo, layout.release()) {
85+
}
7786
#endif
7887

7988
#if GR_TEST_UTILS
@@ -122,47 +131,118 @@ GrBackendTexture::GrBackendTexture(int width,
122131
, fBackend(kMock_GrBackend)
123132
, fMockInfo(mockInfo) {}
124133

134+
GrBackendTexture::~GrBackendTexture() {
135+
this->cleanup();
136+
}
137+
138+
void GrBackendTexture::cleanup() {
125139
#ifdef SK_VULKAN
126-
const GrVkImageInfo* GrBackendTexture::getVkImageInfo() const {
127140
if (this->isValid() && kVulkan_GrBackend == fBackend) {
128-
return &fVkInfo;
141+
fVkInfo.cleanup();
142+
}
143+
#endif
144+
}
145+
146+
GrBackendTexture::GrBackendTexture(const GrBackendTexture& that) : fIsValid(false) {
147+
*this = that;
148+
}
149+
150+
GrBackendTexture& GrBackendTexture::operator=(const GrBackendTexture& that) {
151+
if (!that.isValid()) {
152+
this->cleanup();
153+
fIsValid = false;
154+
return *this;
155+
}
156+
fWidth = that.fWidth;
157+
fHeight = that.fHeight;
158+
fConfig = that.fConfig;
159+
fMipMapped = that.fMipMapped;
160+
fBackend = that.fBackend;
161+
162+
switch (that.fBackend) {
163+
case kOpenGL_GrBackend:
164+
fGLInfo = that.fGLInfo;
165+
break;
166+
#ifdef SK_VULKAN
167+
case kVulkan_GrBackend:
168+
fVkInfo.assign(that.fVkInfo, this->isValid());
169+
break;
170+
#endif
171+
#ifdef SK_METAL
172+
case kMetal_GrBackend:
173+
break;
174+
#endif
175+
case kMock_GrBackend:
176+
fMockInfo = that.fMockInfo;
177+
break;
178+
default:
179+
SK_ABORT("Unknown GrBackend");
180+
}
181+
fIsValid = that.fIsValid;
182+
return *this;
183+
}
184+
185+
#ifdef SK_VULKAN
186+
bool GrBackendTexture::getVkImageInfo(GrVkImageInfo* outInfo) const {
187+
if (this->isValid() && kVulkan_GrBackend == fBackend) {
188+
*outInfo = fVkInfo.snapImageInfo();
189+
return true;
190+
}
191+
return false;
192+
}
193+
194+
void GrBackendTexture::setVkImageLayout(VkImageLayout layout) {
195+
if (this->isValid() && kVulkan_GrBackend == fBackend) {
196+
fVkInfo.setImageLayout(layout);
197+
}
198+
}
199+
200+
sk_sp<GrVkImageLayout> GrBackendTexture::getGrVkImageLayout() const {
201+
if (this->isValid() && kVulkan_GrBackend == fBackend) {
202+
return fVkInfo.getGrVkImageLayout();
129203
}
130204
return nullptr;
131205
}
132206
#endif
133207

134-
const GrGLTextureInfo* GrBackendTexture::getGLTextureInfo() const {
208+
bool GrBackendTexture::getGLTextureInfo(GrGLTextureInfo* outInfo) const {
135209
if (this->isValid() && kOpenGL_GrBackend == fBackend) {
136-
return &fGLInfo;
210+
*outInfo = fGLInfo;
211+
return true;
137212
}
138-
return nullptr;
213+
return false;
139214
}
140215

141-
const GrMockTextureInfo* GrBackendTexture::getMockTextureInfo() const {
216+
bool GrBackendTexture::getMockTextureInfo(GrMockTextureInfo* outInfo) const {
142217
if (this->isValid() && kMock_GrBackend == fBackend) {
143-
return &fMockInfo;
218+
*outInfo = fMockInfo;
219+
return true;
144220
}
145-
return nullptr;
221+
return false;
146222
}
147223

148224
GrBackendFormat GrBackendTexture::format() const {
225+
if (!this->isValid()) {
226+
return GrBackendFormat();
227+
}
228+
149229
switch (this->backend()) {
150230
#ifdef SK_VULKAN
151231
case kVulkan_GrBackend: {
152-
const GrVkImageInfo* vkInfo = this->getVkImageInfo();
153-
SkASSERT(vkInfo);
154-
return GrBackendFormat::MakeVk(vkInfo->fFormat);
232+
GrVkImageInfo vkInfo;
233+
SkAssertResult(this->getVkImageInfo(&vkInfo));
234+
return GrBackendFormat::MakeVk(vkInfo.fFormat);
155235
}
156236
#endif
157237
case kOpenGL_GrBackend: {
158-
const GrGLTextureInfo* glInfo = this->getGLTextureInfo();
159-
SkASSERT(glInfo);
160-
return GrBackendFormat::MakeGL(glInfo->fFormat, glInfo->fTarget);
238+
GrGLTextureInfo glInfo;
239+
SkAssertResult(this->getGLTextureInfo(&glInfo));
240+
return GrBackendFormat::MakeGL(glInfo.fFormat, glInfo.fTarget);
161241
}
162242
case kMock_GrBackend: {
163-
const GrMockTextureInfo* mockInfo = this->getMockTextureInfo();
164-
SkASSERT(mockInfo);
165-
return GrBackendFormat::MakeMock(mockInfo->fConfig);
243+
GrMockTextureInfo mockInfo;
244+
SkAssertResult(this->getMockTextureInfo(&mockInfo));
245+
return GrBackendFormat::MakeMock(mockInfo.fConfig);
166246
}
167247
default:
168248
return GrBackendFormat();

src/gpu/gl/GrGLCaps.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2669,11 +2669,11 @@ bool validate_sized_format(GrGLenum format, SkColorType ct, GrPixelConfig* confi
26692669

26702670
bool GrGLCaps::validateBackendTexture(const GrBackendTexture& tex, SkColorType ct,
26712671
GrPixelConfig* config) const {
2672-
const GrGLTextureInfo* texInfo = tex.getGLTextureInfo();
2673-
if (!texInfo) {
2672+
GrGLTextureInfo texInfo;
2673+
if (!tex.getGLTextureInfo(&texInfo)) {
26742674
return false;
26752675
}
2676-
return validate_sized_format(texInfo->fFormat, ct, config, fStandard);
2676+
return validate_sized_format(texInfo.fFormat, ct, config, fStandard);
26772677
}
26782678

26792679
bool GrGLCaps::validateBackendRenderTarget(const GrBackendRenderTarget& rt, SkColorType ct,

0 commit comments

Comments
 (0)