Skip to content

Commit

Permalink
Update getBackendInfo calls on GrBackendTexture to support VkImageLay…
Browse files Browse the repository at this point in the history
…out 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]>
  • Loading branch information
egdaniel authored and Skia Commit-Bot committed Apr 10, 2018
1 parent 58627cb commit 52e16d9
Show file tree
Hide file tree
Showing 29 changed files with 713 additions and 188 deletions.
3 changes: 3 additions & 0 deletions gn/gpu.gni
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,7 @@ skia_vk_sources = [
"$_include/gpu/vk/GrVkDefines.h",
"$_include/gpu/vk/GrVkInterface.h",
"$_include/gpu/vk/GrVkTypes.h",
"$_include/private/GrVkTypesPriv.h",
"$_src/gpu/vk/GrVkBackendContext.cpp",
"$_src/gpu/vk/GrVkBuffer.cpp",
"$_src/gpu/vk/GrVkBuffer.h",
Expand Down Expand Up @@ -552,6 +553,7 @@ skia_vk_sources = [
"$_src/gpu/vk/GrVkGpuCommandBuffer.h",
"$_src/gpu/vk/GrVkImage.cpp",
"$_src/gpu/vk/GrVkImage.h",
"$_src/gpu/vk/GrVkImageLayout.h",
"$_src/gpu/vk/GrVkImageView.cpp",
"$_src/gpu/vk/GrVkImageView.h",
"$_src/gpu/vk/GrVkIndexBuffer.cpp",
Expand Down Expand Up @@ -589,6 +591,7 @@ skia_vk_sources = [
"$_src/gpu/vk/GrVkTextureRenderTarget.h",
"$_src/gpu/vk/GrVkTransferBuffer.cpp",
"$_src/gpu/vk/GrVkTransferBuffer.h",
"$_src/gpu/vk/GrVkTypesPriv.cpp",
"$_src/gpu/vk/GrVkUniformBuffer.cpp",
"$_src/gpu/vk/GrVkUniformBuffer.h",
"$_src/gpu/vk/GrVkUniformHandler.cpp",
Expand Down
1 change: 1 addition & 0 deletions gn/tests.gni
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ tests_sources = [
"$_tests/UnicodeTest.cpp",
"$_tests/UtilsTest.cpp",
"$_tests/VerticesTest.cpp",
"$_tests/VkBackendSurfaceTest.cpp",
"$_tests/VkHeapTests.cpp",
"$_tests/VkMakeCopyPipelineTest.cpp",
"$_tests/VkUploadPixelsTests.cpp",
Expand Down
46 changes: 36 additions & 10 deletions include/gpu/GrBackendSurface.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@

#ifdef SK_VULKAN
#include "vk/GrVkTypes.h"
#include "../private/GrVkTypesPriv.h"

class GrVkImageLayout;
#endif

#if !SK_SUPPORT_GPU
Expand Down Expand Up @@ -136,24 +139,33 @@ class SK_API GrBackendTexture {
GrMipMapped,
const GrMockTextureInfo& mockInfo);

GrBackendTexture(const GrBackendTexture& that);

~GrBackendTexture();

GrBackendTexture& operator=(const GrBackendTexture& that);

int width() const { return fWidth; }
int height() const { return fHeight; }
bool hasMipMaps() const { return GrMipMapped::kYes == fMipMapped; }
GrBackend backend() const {return fBackend; }

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

#ifdef SK_VULKAN
// If the backend API is Vulkan, this returns a pointer to the GrVkImageInfo struct. Otherwise
// it returns nullptr.
const GrVkImageInfo* getVkImageInfo() const;
// If the backend API is Vulkan, copies a snapshot of the GrGLImageInfo struct into the passed
// in pointer and returns true. This snapshot will set the fImageLayout to the current layout
// state. Otherwise returns false if the backend API is not Vulkan.
bool getVkImageInfo(GrVkImageInfo*) const;

void setVkImageLayout(VkImageLayout);
#endif

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

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

GrPixelConfig config() const { return fConfig; }

#ifdef SK_VULKAN
// Requires friending of GrVkGpu (done above already)
sk_sp<GrVkImageLayout> getGrVkImageLayout() const;

friend class GrVkTexture;
GrBackendTexture(int width,
int height,
const GrVkImageInfo& vkInfo,
sk_sp<GrVkImageLayout> layout);
#endif

// Free and release and resources being held by the GrBackendTexture.
void cleanup();

bool fIsValid;
int fWidth; //<! width in pixels
int fHeight; //<! height in pixels
Expand All @@ -192,7 +218,7 @@ class SK_API GrBackendTexture {
union {
GrGLTextureInfo fGLInfo;
#ifdef SK_VULKAN
GrVkImageInfo fVkInfo;
GrVkBackendSurfaceInfo fVkInfo;
#endif
GrMockTextureInfo fMockInfo;
};
Expand Down
16 changes: 16 additions & 0 deletions include/gpu/vk/GrVkTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,22 @@ struct GrVkImageInfo {
VkFormat fFormat;
uint32_t fLevelCount;

GrVkImageInfo()
: fImage(VK_NULL_HANDLE)
, fAlloc()
, fImageTiling(VK_IMAGE_TILING_OPTIMAL)
, fImageLayout(VK_IMAGE_LAYOUT_UNDEFINED)
, fFormat(VK_FORMAT_UNDEFINED)
, fLevelCount(0) {}

GrVkImageInfo(const GrVkImageInfo& info, VkImageLayout layout)
: fImage(info.fImage)
, fAlloc(info.fAlloc)
, fImageTiling(info.fImageTiling)
, fImageLayout(layout)
, fFormat(info.fFormat)
, fLevelCount(info.fLevelCount) {}

// This gives a way for a client to update the layout of the Image if they change the layout
// while we're still holding onto the wrapped texture. They will first need to get a handle
// to our internal GrVkImageInfo by calling getTextureHandle on a GrVkTexture.
Expand Down
49 changes: 49 additions & 0 deletions include/private/GrVkTypesPriv.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright 2018 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/

#ifndef GrVkTypesPriv_DEFINED
#define GrVkTypesPriv_DEFINED

#include "GrVkTypes.h"
#include "SkRefCnt.h"

class GrVkImageLayout;

// This struct is to used to store the the actual information about the vulkan backend image on the
// GrBackendTexture and GrBackendRenderTarget. When a client calls getVkImageInfo on a
// GrBackendTexture/RenderTarget, we use the GrVkBackendSurfaceInfo to create a snapshot
// GrVkImgeInfo object. Internally, this uses a ref count GrVkImageLayout object to track the
// current VkImageLayout which can be shared with an internal GrVkImage so that layout updates can
// be seen by all users of the image.
struct GrVkBackendSurfaceInfo {
GrVkBackendSurfaceInfo(GrVkImageInfo info, GrVkImageLayout* layout)
: fImageInfo(info), fLayout(layout) {}

void cleanup();

GrVkBackendSurfaceInfo& operator=(const GrVkBackendSurfaceInfo&) = delete;

// Assigns the passed in GrVkBackendSurfaceInfo to this object. if isValid is true we will also
// attempt to unref the old fLayout on this object.
void assign(const GrVkBackendSurfaceInfo&, bool isValid);

void setImageLayout(VkImageLayout layout);

sk_sp<GrVkImageLayout> getGrVkImageLayout() const;

GrVkImageInfo snapImageInfo() const;

#if GR_TEST_UTILS
bool operator==(const GrVkBackendSurfaceInfo& that) const;
#endif

private:
GrVkImageInfo fImageInfo;
GrVkImageLayout* fLayout;
};

#endif
116 changes: 98 additions & 18 deletions src/gpu/GrBackendSurface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "gl/GrGLUtil.h"

#ifdef SK_VULKAN
#include "vk/GrVkImageLayout.h"
#include "vk/GrVkTypes.h"
#include "vk/GrVkUtil.h"
#endif
Expand Down Expand Up @@ -67,13 +68,21 @@ const GrPixelConfig* GrBackendFormat::getMockFormat() const {
GrBackendTexture::GrBackendTexture(int width,
int height,
const GrVkImageInfo& vkInfo)
: GrBackendTexture(width, height, vkInfo,
sk_sp<GrVkImageLayout>(new GrVkImageLayout(vkInfo.fImageLayout))) {}

GrBackendTexture::GrBackendTexture(int width,
int height,
const GrVkImageInfo& vkInfo,
sk_sp<GrVkImageLayout> layout)
: fIsValid(true)
, fWidth(width)
, fHeight(height)
, fConfig(GrVkFormatToPixelConfig(vkInfo.fFormat))
, fMipMapped(GrMipMapped(vkInfo.fLevelCount > 1))
, fBackend(kVulkan_GrBackend)
, fVkInfo(vkInfo) {}
, fVkInfo(vkInfo, layout.release()) {
}
#endif

#if GR_TEST_UTILS
Expand Down Expand Up @@ -122,47 +131,118 @@ GrBackendTexture::GrBackendTexture(int width,
, fBackend(kMock_GrBackend)
, fMockInfo(mockInfo) {}

GrBackendTexture::~GrBackendTexture() {
this->cleanup();
}

void GrBackendTexture::cleanup() {
#ifdef SK_VULKAN
const GrVkImageInfo* GrBackendTexture::getVkImageInfo() const {
if (this->isValid() && kVulkan_GrBackend == fBackend) {
return &fVkInfo;
fVkInfo.cleanup();
}
#endif
}

GrBackendTexture::GrBackendTexture(const GrBackendTexture& that) : fIsValid(false) {
*this = that;
}

GrBackendTexture& GrBackendTexture::operator=(const GrBackendTexture& that) {
if (!that.isValid()) {
this->cleanup();
fIsValid = false;
return *this;
}
fWidth = that.fWidth;
fHeight = that.fHeight;
fConfig = that.fConfig;
fMipMapped = that.fMipMapped;
fBackend = that.fBackend;

switch (that.fBackend) {
case kOpenGL_GrBackend:
fGLInfo = that.fGLInfo;
break;
#ifdef SK_VULKAN
case kVulkan_GrBackend:
fVkInfo.assign(that.fVkInfo, this->isValid());
break;
#endif
#ifdef SK_METAL
case kMetal_GrBackend:
break;
#endif
case kMock_GrBackend:
fMockInfo = that.fMockInfo;
break;
default:
SK_ABORT("Unknown GrBackend");
}
fIsValid = that.fIsValid;
return *this;
}

#ifdef SK_VULKAN
bool GrBackendTexture::getVkImageInfo(GrVkImageInfo* outInfo) const {
if (this->isValid() && kVulkan_GrBackend == fBackend) {
*outInfo = fVkInfo.snapImageInfo();
return true;
}
return false;
}

void GrBackendTexture::setVkImageLayout(VkImageLayout layout) {
if (this->isValid() && kVulkan_GrBackend == fBackend) {
fVkInfo.setImageLayout(layout);
}
}

sk_sp<GrVkImageLayout> GrBackendTexture::getGrVkImageLayout() const {
if (this->isValid() && kVulkan_GrBackend == fBackend) {
return fVkInfo.getGrVkImageLayout();
}
return nullptr;
}
#endif

const GrGLTextureInfo* GrBackendTexture::getGLTextureInfo() const {
bool GrBackendTexture::getGLTextureInfo(GrGLTextureInfo* outInfo) const {
if (this->isValid() && kOpenGL_GrBackend == fBackend) {
return &fGLInfo;
*outInfo = fGLInfo;
return true;
}
return nullptr;
return false;
}

const GrMockTextureInfo* GrBackendTexture::getMockTextureInfo() const {
bool GrBackendTexture::getMockTextureInfo(GrMockTextureInfo* outInfo) const {
if (this->isValid() && kMock_GrBackend == fBackend) {
return &fMockInfo;
*outInfo = fMockInfo;
return true;
}
return nullptr;
return false;
}

GrBackendFormat GrBackendTexture::format() const {
if (!this->isValid()) {
return GrBackendFormat();
}

switch (this->backend()) {
#ifdef SK_VULKAN
case kVulkan_GrBackend: {
const GrVkImageInfo* vkInfo = this->getVkImageInfo();
SkASSERT(vkInfo);
return GrBackendFormat::MakeVk(vkInfo->fFormat);
GrVkImageInfo vkInfo;
SkAssertResult(this->getVkImageInfo(&vkInfo));
return GrBackendFormat::MakeVk(vkInfo.fFormat);
}
#endif
case kOpenGL_GrBackend: {
const GrGLTextureInfo* glInfo = this->getGLTextureInfo();
SkASSERT(glInfo);
return GrBackendFormat::MakeGL(glInfo->fFormat, glInfo->fTarget);
GrGLTextureInfo glInfo;
SkAssertResult(this->getGLTextureInfo(&glInfo));
return GrBackendFormat::MakeGL(glInfo.fFormat, glInfo.fTarget);
}
case kMock_GrBackend: {
const GrMockTextureInfo* mockInfo = this->getMockTextureInfo();
SkASSERT(mockInfo);
return GrBackendFormat::MakeMock(mockInfo->fConfig);
GrMockTextureInfo mockInfo;
SkAssertResult(this->getMockTextureInfo(&mockInfo));
return GrBackendFormat::MakeMock(mockInfo.fConfig);
}
default:
return GrBackendFormat();
Expand Down
6 changes: 3 additions & 3 deletions src/gpu/gl/GrGLCaps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2669,11 +2669,11 @@ bool validate_sized_format(GrGLenum format, SkColorType ct, GrPixelConfig* confi

bool GrGLCaps::validateBackendTexture(const GrBackendTexture& tex, SkColorType ct,
GrPixelConfig* config) const {
const GrGLTextureInfo* texInfo = tex.getGLTextureInfo();
if (!texInfo) {
GrGLTextureInfo texInfo;
if (!tex.getGLTextureInfo(&texInfo)) {
return false;
}
return validate_sized_format(texInfo->fFormat, ct, config, fStandard);
return validate_sized_format(texInfo.fFormat, ct, config, fStandard);
}

bool GrGLCaps::validateBackendRenderTarget(const GrBackendRenderTarget& rt, SkColorType ct,
Expand Down
Loading

0 comments on commit 52e16d9

Please sign in to comment.