Add API to invalidate GL texture parameters from GrBackendTexture.
This is modeled on how we coordinate VkImage layout changes between GrContext and clients. A type GrGLTextureParameters is used to track the current parameter state. When a client creates a GrBackendTexture in order to wrap a resource they created a new GrGLTextureParameters is created and the wrapped GrGLTexture will share ownership. When GrContext creates a non-wrapped GrGLTexture, the GrGLTexture creates a new GrGLTextureParameters and any GrBackendTextures created from that GrGLTexture will share ownership. Clients indicate parameter changes by calling GrBackendTexture::glTextureParametersModified(). We still assume all texture parameters may have changed after a call to GrContext::resetContext() (for now). The "timestamp" that is used to implement this has been moved from GrGpu to GrGLGpu as there were no other use cases. Change-Id: Ic24e00488fad254a29d5eec6890278b67df6efae Bug: skia:7966 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/217385 Auto-Submit: Brian Salomon <bsalomon@google.com> Commit-Queue: Greg Daniel <egdaniel@google.com> Reviewed-by: Greg Daniel <egdaniel@google.com>
This commit is contained in:
parent
9893f8e151
commit
e2826ab59c
@ -35,6 +35,7 @@ skia_gpu_sources = [
|
||||
"$_include/private/GrAuditTrail.h",
|
||||
"$_include/private/GrColor.h",
|
||||
"$_include/private/GrContext_Base.h",
|
||||
"$_include/private/GrGLTypesPriv.h",
|
||||
"$_include/private/GrImageContext.h",
|
||||
"$_include/private/GrOpList.h",
|
||||
"$_include/private/GrProxyRef.h",
|
||||
@ -471,6 +472,7 @@ skia_gpu_sources = [
|
||||
"$_src/gpu/gl/GrGLTexture.h",
|
||||
"$_src/gpu/gl/GrGLTextureRenderTarget.cpp",
|
||||
"$_src/gpu/gl/GrGLTextureRenderTarget.h",
|
||||
"$_src/gpu/gl/GrGLTypesPriv.cpp",
|
||||
"$_src/gpu/gl/GrGLUtil.cpp",
|
||||
"$_src/gpu/gl/GrGLUtil.h",
|
||||
"$_src/gpu/gl/GrGLUniformHandler.cpp",
|
||||
|
@ -89,6 +89,7 @@ tests_sources = [
|
||||
"$_tests/GLProgramsTest.cpp",
|
||||
"$_tests/GeometryTest.cpp",
|
||||
"$_tests/GifTest.cpp",
|
||||
"$_tests/GLBackendSurfaceTest.cpp",
|
||||
"$_tests/GlyphRunTest.cpp",
|
||||
"$_tests/GpuDrawPathTest.cpp",
|
||||
"$_tests/GpuRectanizerTest.cpp",
|
||||
|
@ -12,9 +12,11 @@
|
||||
#include "include/gpu/gl/GrGLTypes.h"
|
||||
#include "include/gpu/mock/GrMockTypes.h"
|
||||
#include "include/gpu/vk/GrVkTypes.h"
|
||||
#include "include/private/GrGLTypesPriv.h"
|
||||
#include "include/private/GrVkTypesPriv.h"
|
||||
|
||||
class GrVkImageLayout;
|
||||
class GrGLTextureParameters;
|
||||
|
||||
#ifdef SK_METAL
|
||||
#include "include/gpu/mtl/GrMtlTypes.h"
|
||||
@ -171,6 +173,10 @@ public:
|
||||
// pointer and returns true. Otherwise returns false if the backend API is not GL.
|
||||
bool getGLTextureInfo(GrGLTextureInfo*) const;
|
||||
|
||||
// Call this to indicate that the texture parameters have been modified in the GL context
|
||||
// externally to GrContext.
|
||||
void glTextureParametersModified();
|
||||
|
||||
// If the backend API is Vulkan, copies a snapshot of the GrVkImageInfo 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.
|
||||
@ -229,15 +235,23 @@ private:
|
||||
|
||||
GrPixelConfig config() const { return fConfig; }
|
||||
|
||||
// Requires friending of GrVkGpu (done above already)
|
||||
sk_sp<GrVkImageLayout> getGrVkImageLayout() const;
|
||||
#ifdef SK_GL
|
||||
friend class GrGLTexture;
|
||||
GrBackendTexture(int width,
|
||||
int height,
|
||||
GrMipMapped,
|
||||
const GrGLTextureInfo,
|
||||
sk_sp<GrGLTextureParameters>);
|
||||
sk_sp<GrGLTextureParameters> getGLTextureParams() const;
|
||||
#endif
|
||||
|
||||
friend class GrVkTexture;
|
||||
#ifdef SK_VULKAN
|
||||
GrBackendTexture(int width,
|
||||
int height,
|
||||
const GrVkImageInfo& vkInfo,
|
||||
sk_sp<GrVkImageLayout> layout);
|
||||
friend class GrVkTexture;
|
||||
GrBackendTexture(int width,
|
||||
int height,
|
||||
const GrVkImageInfo& vkInfo,
|
||||
sk_sp<GrVkImageLayout> layout);
|
||||
sk_sp<GrVkImageLayout> getGrVkImageLayout() const;
|
||||
#endif
|
||||
|
||||
// Free and release and resources being held by the GrBackendTexture.
|
||||
@ -251,7 +265,9 @@ private:
|
||||
GrBackendApi fBackend;
|
||||
|
||||
union {
|
||||
GrGLTextureInfo fGLInfo;
|
||||
#ifdef SK_GL
|
||||
GrGLBackendTextureInfo fGLInfo;
|
||||
#endif
|
||||
GrVkBackendSurfaceInfo fVkInfo;
|
||||
GrMockTextureInfo fMockInfo;
|
||||
};
|
||||
|
92
include/private/GrGLTypesPriv.h
Normal file
92
include/private/GrGLTypesPriv.h
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2019 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/gpu/gl/GrGLTypes.h"
|
||||
|
||||
#ifndef GrGLTypesPriv_DEFINED
|
||||
#define GrGLTypesPriv_DEFINED
|
||||
|
||||
class GrGLTextureParameters : public SkNVRefCnt<GrGLTextureParameters> {
|
||||
public:
|
||||
// We currently consider texture parameters invalid on all textures
|
||||
// GrContext::resetContext(). We use this type to track whether instances of
|
||||
// GrGLTextureParameters were updated before or after the most recent resetContext(). At 10
|
||||
// resets / frame and 60fps a 64bit timestamp will overflow in about a billion years.
|
||||
// TODO: Require clients to use GrBackendTexture::glTextureParametersModified() to invalidate
|
||||
// texture parameters and get rid of timestamp checking.
|
||||
using ResetTimestamp = uint64_t;
|
||||
|
||||
// This initializes the params to have an expired timestamp. They'll be considered invalid the
|
||||
// first time the texture is used unless set() is called.
|
||||
GrGLTextureParameters() = default;
|
||||
|
||||
// This is texture parameter state that is overridden when a non-zero sampler object is bound.
|
||||
struct SamplerOverriddenState {
|
||||
SamplerOverriddenState();
|
||||
void invalidate();
|
||||
|
||||
GrGLenum fMinFilter;
|
||||
GrGLenum fMagFilter;
|
||||
GrGLenum fWrapS;
|
||||
GrGLenum fWrapT;
|
||||
GrGLfloat fMinLOD;
|
||||
GrGLfloat fMaxLOD;
|
||||
// We always want the border color to be transparent black, so no need to store 4 floats.
|
||||
// Just track if it's been invalidated and no longer the default
|
||||
bool fBorderColorInvalid;
|
||||
};
|
||||
|
||||
// Texture parameter state that is not overridden by a bound sampler object.
|
||||
struct NonsamplerState {
|
||||
NonsamplerState();
|
||||
void invalidate();
|
||||
|
||||
uint32_t fSwizzleKey;
|
||||
GrGLint fBaseMipMapLevel;
|
||||
GrGLint fMaxMipMapLevel;
|
||||
};
|
||||
|
||||
void invalidate();
|
||||
|
||||
ResetTimestamp resetTimestamp() const { return fResetTimestamp; }
|
||||
const SamplerOverriddenState& samplerOverriddenState() const { return fSamplerOverriddenState; }
|
||||
const NonsamplerState& nonsamplerState() const { return fNonsamplerState; }
|
||||
|
||||
// SamplerOverriddenState is optional because we don't track it when we're using sampler
|
||||
// objects.
|
||||
void set(const SamplerOverriddenState* samplerState,
|
||||
const NonsamplerState& nonsamplerState,
|
||||
ResetTimestamp currTimestamp);
|
||||
|
||||
private:
|
||||
static constexpr ResetTimestamp kExpiredTimestamp = 0;
|
||||
|
||||
SamplerOverriddenState fSamplerOverriddenState;
|
||||
NonsamplerState fNonsamplerState;
|
||||
ResetTimestamp fResetTimestamp = kExpiredTimestamp;
|
||||
};
|
||||
|
||||
class GrGLBackendTextureInfo {
|
||||
public:
|
||||
GrGLBackendTextureInfo(const GrGLTextureInfo& info, GrGLTextureParameters* params)
|
||||
: fInfo(info), fParams(params) {}
|
||||
GrGLBackendTextureInfo(const GrGLBackendTextureInfo&) = delete;
|
||||
GrGLBackendTextureInfo& operator=(const GrGLBackendTextureInfo&) = delete;
|
||||
const GrGLTextureInfo& info() const { return fInfo; }
|
||||
GrGLTextureParameters* parameters() const { return fParams; }
|
||||
sk_sp<GrGLTextureParameters> refParameters() const { return sk_ref_sp(fParams); }
|
||||
|
||||
void cleanup();
|
||||
void assign(const GrGLBackendTextureInfo&, bool thisIsValid);
|
||||
|
||||
private:
|
||||
GrGLTextureInfo fInfo;
|
||||
GrGLTextureParameters* fParams;
|
||||
};
|
||||
|
||||
#endif
|
@ -187,6 +187,28 @@ GrBackendTexture::GrBackendTexture(int width,
|
||||
: fIsValid(false) {}
|
||||
#endif
|
||||
|
||||
#ifdef SK_GL
|
||||
GrBackendTexture::GrBackendTexture(int width,
|
||||
int height,
|
||||
GrMipMapped mipMapped,
|
||||
const GrGLTextureInfo glInfo,
|
||||
sk_sp<GrGLTextureParameters> params)
|
||||
: fIsValid(true)
|
||||
, fWidth(width)
|
||||
, fHeight(height)
|
||||
, fConfig(kUnknown_GrPixelConfig)
|
||||
, fMipMapped(mipMapped)
|
||||
, fBackend(GrBackendApi::kOpenGL)
|
||||
, fGLInfo(glInfo, params.release()) {}
|
||||
|
||||
sk_sp<GrGLTextureParameters> GrBackendTexture::getGLTextureParams() const {
|
||||
if (fBackend != GrBackendApi::kOpenGL) {
|
||||
return nullptr;
|
||||
}
|
||||
return fGLInfo.refParameters();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SK_VULKAN
|
||||
GrBackendTexture::GrBackendTexture(int width,
|
||||
int height,
|
||||
@ -220,13 +242,10 @@ GrBackendTexture::GrBackendTexture(int width,
|
||||
int height,
|
||||
GrMipMapped mipMapped,
|
||||
const GrGLTextureInfo& glInfo)
|
||||
: fIsValid(true)
|
||||
, fWidth(width)
|
||||
, fHeight(height)
|
||||
, fConfig(kUnknown_GrPixelConfig)
|
||||
, fMipMapped(mipMapped)
|
||||
, fBackend(GrBackendApi::kOpenGL)
|
||||
, fGLInfo(glInfo) {}
|
||||
: GrBackendTexture(width, height, mipMapped, glInfo, sk_make_sp<GrGLTextureParameters>()) {
|
||||
// Make no assumptions about client's texture's parameters.
|
||||
this->glTextureParametersModified();
|
||||
}
|
||||
|
||||
GrBackendTexture::GrBackendTexture(int width,
|
||||
int height,
|
||||
@ -245,6 +264,11 @@ GrBackendTexture::~GrBackendTexture() {
|
||||
}
|
||||
|
||||
void GrBackendTexture::cleanup() {
|
||||
#ifdef SK_GL
|
||||
if (this->isValid() && GrBackendApi::kOpenGL == fBackend) {
|
||||
fGLInfo.cleanup();
|
||||
}
|
||||
#endif
|
||||
#ifdef SK_VULKAN
|
||||
if (this->isValid() && GrBackendApi::kVulkan == fBackend) {
|
||||
fVkInfo.cleanup();
|
||||
@ -261,6 +285,9 @@ GrBackendTexture& GrBackendTexture::operator=(const GrBackendTexture& that) {
|
||||
this->cleanup();
|
||||
fIsValid = false;
|
||||
return *this;
|
||||
} else if (this->fBackend != that.fBackend) {
|
||||
this->cleanup();
|
||||
fIsValid = false;
|
||||
}
|
||||
fWidth = that.fWidth;
|
||||
fHeight = that.fHeight;
|
||||
@ -269,14 +296,16 @@ GrBackendTexture& GrBackendTexture::operator=(const GrBackendTexture& that) {
|
||||
fBackend = that.fBackend;
|
||||
|
||||
switch (that.fBackend) {
|
||||
#ifdef SK_GL
|
||||
case GrBackendApi::kOpenGL:
|
||||
fGLInfo = that.fGLInfo;
|
||||
fGLInfo.assign(that.fGLInfo, this->isValid());
|
||||
break;
|
||||
case GrBackendApi::kVulkan:
|
||||
#ifdef SK_VULKAN
|
||||
fVkInfo.assign(that.fVkInfo, this->isValid());
|
||||
#endif
|
||||
#ifdef SK_VULKAN
|
||||
case GrBackendApi::kVulkan:
|
||||
fVkInfo.assign(that.fVkInfo, this->isValid());
|
||||
break;
|
||||
#endif
|
||||
#ifdef SK_METAL
|
||||
case GrBackendApi::kMetal:
|
||||
fMtlInfo = that.fMtlInfo;
|
||||
@ -288,7 +317,7 @@ GrBackendTexture& GrBackendTexture::operator=(const GrBackendTexture& that) {
|
||||
default:
|
||||
SK_ABORT("Unknown GrBackend");
|
||||
}
|
||||
fIsValid = that.fIsValid;
|
||||
fIsValid = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -310,21 +339,14 @@ void GrBackendTexture::setVkImageLayout(VkImageLayout layout) {
|
||||
#endif
|
||||
}
|
||||
|
||||
// We need a stubbed version of GrVkImageLayout for non vulkan builds
|
||||
#ifndef SK_VULKAN
|
||||
class GrVkImageLayout : public SkRefCnt {
|
||||
GrVkImageLayout(VkImageLayout layout) {}
|
||||
};
|
||||
#endif
|
||||
|
||||
sk_sp<GrVkImageLayout> GrBackendTexture::getGrVkImageLayout() const {
|
||||
#ifdef SK_VULKAN
|
||||
sk_sp<GrVkImageLayout> GrBackendTexture::getGrVkImageLayout() const {
|
||||
if (this->isValid() && GrBackendApi::kVulkan == fBackend) {
|
||||
return fVkInfo.getGrVkImageLayout();
|
||||
}
|
||||
#endif
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SK_METAL
|
||||
bool GrBackendTexture::getMtlTextureInfo(GrMtlTextureInfo* outInfo) const {
|
||||
@ -337,8 +359,9 @@ bool GrBackendTexture::getMtlTextureInfo(GrMtlTextureInfo* outInfo) const {
|
||||
#endif
|
||||
|
||||
bool GrBackendTexture::getGLTextureInfo(GrGLTextureInfo* outInfo) const {
|
||||
#ifdef SK_GL
|
||||
if (this->isValid() && GrBackendApi::kOpenGL == fBackend) {
|
||||
*outInfo = fGLInfo;
|
||||
*outInfo = fGLInfo.info();
|
||||
return true;
|
||||
} else if (this->isValid() && GrBackendApi::kMock == fBackend) {
|
||||
// Hack! This allows some blink unit tests to work when using the Mock GrContext.
|
||||
@ -349,9 +372,18 @@ bool GrBackendTexture::getGLTextureInfo(GrGLTextureInfo* outInfo) const {
|
||||
GR_GL_RGBA8 };
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
void GrBackendTexture::glTextureParametersModified() {
|
||||
#ifdef SK_GL
|
||||
if (this->isValid() && fBackend == GrBackendApi::kOpenGL) {
|
||||
fGLInfo.parameters()->invalidate();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool GrBackendTexture::getMockTextureInfo(GrMockTextureInfo* outInfo) const {
|
||||
if (this->isValid() && GrBackendApi::kMock == fBackend) {
|
||||
*outInfo = fMockInfo;
|
||||
@ -368,8 +400,10 @@ bool GrBackendTexture::isSameTexture(const GrBackendTexture& that) {
|
||||
return false;
|
||||
}
|
||||
switch (fBackend) {
|
||||
#ifdef SK_GL
|
||||
case GrBackendApi::kOpenGL:
|
||||
return fGLInfo.fID == that.fGLInfo.fID;
|
||||
return fGLInfo.info().fID == that.fGLInfo.info().fID;
|
||||
#endif
|
||||
#ifdef SK_VULKAN
|
||||
case GrBackendApi::kVulkan:
|
||||
return fVkInfo.snapImageInfo().fImage == that.fVkInfo.snapImageInfo().fImage;
|
||||
@ -390,8 +424,10 @@ GrBackendFormat GrBackendTexture::getBackendFormat() const {
|
||||
return GrBackendFormat();
|
||||
}
|
||||
switch (fBackend) {
|
||||
#ifdef SK_GL
|
||||
case GrBackendApi::kOpenGL:
|
||||
return GrBackendFormat::MakeGL(fGLInfo.fFormat, fGLInfo.fTarget);
|
||||
return GrBackendFormat::MakeGL(fGLInfo.info().fFormat, fGLInfo.info().fTarget);
|
||||
#endif
|
||||
#ifdef SK_VULKAN
|
||||
case GrBackendApi::kVulkan: {
|
||||
auto info = fVkInfo.snapImageInfo();
|
||||
@ -431,28 +467,23 @@ bool GrBackendTexture::TestingOnly_Equals(const GrBackendTexture& t0, const GrBa
|
||||
}
|
||||
|
||||
switch (t0.fBackend) {
|
||||
case GrBackendApi::kOpenGL:
|
||||
return t0.fGLInfo == t1.fGLInfo;
|
||||
case GrBackendApi::kMock:
|
||||
return t0.fMockInfo == t1.fMockInfo;
|
||||
case GrBackendApi::kVulkan:
|
||||
#ifdef SK_GL
|
||||
case GrBackendApi::kOpenGL:
|
||||
return t0.fGLInfo.info() == t1.fGLInfo.info();
|
||||
#endif
|
||||
case GrBackendApi::kMock:
|
||||
return t0.fMockInfo == t1.fMockInfo;
|
||||
#ifdef SK_VULKAN
|
||||
return t0.fVkInfo == t1.fVkInfo;
|
||||
#else
|
||||
// fall through
|
||||
case GrBackendApi::kVulkan:
|
||||
return t0.fVkInfo == t1.fVkInfo;
|
||||
#endif
|
||||
case GrBackendApi::kMetal:
|
||||
#ifdef SK_METAL
|
||||
return t0.fMtlInfo == t1.fMtlInfo;
|
||||
#else
|
||||
// fall through
|
||||
case GrBackendApi::kMetal:
|
||||
return t0.fMtlInfo == t1.fMtlInfo;
|
||||
#endif
|
||||
default:
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
SkASSERT(0);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -559,6 +590,9 @@ GrBackendRenderTarget& GrBackendRenderTarget::operator=(const GrBackendRenderTar
|
||||
this->cleanup();
|
||||
fIsValid = false;
|
||||
return *this;
|
||||
} else if (this->fBackend != that.fBackend) {
|
||||
this->cleanup();
|
||||
fIsValid = false;
|
||||
}
|
||||
fWidth = that.fWidth;
|
||||
fHeight = that.fHeight;
|
||||
@ -609,14 +643,14 @@ void GrBackendRenderTarget::setVkImageLayout(VkImageLayout layout) {
|
||||
#endif
|
||||
}
|
||||
|
||||
sk_sp<GrVkImageLayout> GrBackendRenderTarget::getGrVkImageLayout() const {
|
||||
#ifdef SK_VULKAN
|
||||
sk_sp<GrVkImageLayout> GrBackendRenderTarget::getGrVkImageLayout() const {
|
||||
if (this->isValid() && GrBackendApi::kVulkan == fBackend) {
|
||||
return fVkInfo.getGrVkImageLayout();
|
||||
}
|
||||
#endif
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SK_METAL
|
||||
bool GrBackendRenderTarget::getMtlTextureInfo(GrMtlTextureInfo* outInfo) const {
|
||||
@ -661,24 +695,22 @@ bool GrBackendRenderTarget::TestingOnly_Equals(const GrBackendRenderTarget& r0,
|
||||
}
|
||||
|
||||
switch (r0.fBackend) {
|
||||
case GrBackendApi::kOpenGL:
|
||||
return r0.fGLInfo == r1.fGLInfo;
|
||||
case GrBackendApi::kMock:
|
||||
return r0.fMockInfo == r1.fMockInfo;
|
||||
case GrBackendApi::kVulkan:
|
||||
#ifdef SK_GL
|
||||
case GrBackendApi::kOpenGL:
|
||||
return r0.fGLInfo == r1.fGLInfo;
|
||||
#endif
|
||||
case GrBackendApi::kMock:
|
||||
return r0.fMockInfo == r1.fMockInfo;
|
||||
#ifdef SK_VULKAN
|
||||
return r0.fVkInfo == r1.fVkInfo;
|
||||
#else
|
||||
// fall through
|
||||
case GrBackendApi::kVulkan:
|
||||
return r0.fVkInfo == r1.fVkInfo;
|
||||
#endif
|
||||
case GrBackendApi::kMetal:
|
||||
#ifdef SK_METAL
|
||||
return r0.fMtlInfo == r1.fMtlInfo;
|
||||
#else
|
||||
// fall through
|
||||
case GrBackendApi::kMetal:
|
||||
return r0.fMtlInfo == r1.fMtlInfo;
|
||||
#endif
|
||||
default:
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
SkASSERT(0);
|
||||
|
@ -32,11 +32,7 @@
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GrGpu::GrGpu(GrContext* context)
|
||||
: fResetTimestamp(kExpiredTimestamp+1)
|
||||
, fResetBits(kAll_GrBackendState)
|
||||
, fContext(context) {
|
||||
}
|
||||
GrGpu::GrGpu(GrContext* context) : fResetBits(kAll_GrBackendState), fContext(context) {}
|
||||
|
||||
GrGpu::~GrGpu() {}
|
||||
|
||||
|
@ -249,20 +249,6 @@ public:
|
||||
GrColorType bufferColorType, GrGpuBuffer* transferBuffer,
|
||||
size_t offset);
|
||||
|
||||
// After the client interacts directly with the 3D context state the GrGpu
|
||||
// must resync its internal state and assumptions about 3D context state.
|
||||
// Each time this occurs the GrGpu bumps a timestamp.
|
||||
// state of the 3D context
|
||||
// At 10 resets / frame and 60fps a 64bit timestamp will overflow in about
|
||||
// a billion years.
|
||||
typedef uint64_t ResetTimestamp;
|
||||
|
||||
// This timestamp is always older than the current timestamp
|
||||
static const ResetTimestamp kExpiredTimestamp = 0;
|
||||
// Returns a timestamp based on the number of times the context was reset.
|
||||
// This timestamp can be used to lazily detect when cached 3D context state
|
||||
// is dirty.
|
||||
ResetTimestamp getResetTimestamp() const { return fResetTimestamp; }
|
||||
|
||||
// Called to perform a surface to surface copy. Fallbacks to issuing a draw from the src to dst
|
||||
// take place at the GrOpList level and this function implement faster copy paths. The rect
|
||||
@ -566,10 +552,8 @@ private:
|
||||
void resetContext() {
|
||||
this->onResetContext(fResetBits);
|
||||
fResetBits = 0;
|
||||
++fResetTimestamp;
|
||||
}
|
||||
|
||||
ResetTimestamp fResetTimestamp;
|
||||
uint32_t fResetBits;
|
||||
// The context owns us, not vice-versa, so this ptr is not ref'ed by Gpu.
|
||||
GrContext* fContext;
|
||||
|
@ -655,6 +655,7 @@ void GrGLGpu::onResetContext(uint32_t resetBits) {
|
||||
fHWProgramID = 0;
|
||||
fHWProgram.reset();
|
||||
}
|
||||
++fResetTimestampForTextureParameters;
|
||||
}
|
||||
|
||||
static bool check_backend_texture(const GrBackendTexture& backendTex, const GrGLCaps& caps,
|
||||
@ -706,8 +707,8 @@ sk_sp<GrTexture> GrGLGpu::onWrapBackendTexture(const GrBackendTexture& backendTe
|
||||
GrMipMapsStatus mipMapsStatus = backendTex.hasMipMaps() ? GrMipMapsStatus::kValid
|
||||
: GrMipMapsStatus::kNotAllocated;
|
||||
|
||||
auto texture =
|
||||
GrGLTexture::MakeWrapped(this, surfDesc, mipMapsStatus, idDesc, cacheable, ioType);
|
||||
auto texture = GrGLTexture::MakeWrapped(this, surfDesc, mipMapsStatus, idDesc,
|
||||
backendTex.getGLTextureParams(), cacheable, ioType);
|
||||
// We don't know what parameters are already set on wrapped textures.
|
||||
texture->textureParamsModified();
|
||||
return std::move(texture);
|
||||
@ -755,7 +756,8 @@ sk_sp<GrTexture> GrGLGpu::onWrapRenderableBackendTexture(const GrBackendTexture&
|
||||
: GrMipMapsStatus::kNotAllocated;
|
||||
|
||||
sk_sp<GrGLTextureRenderTarget> texRT(GrGLTextureRenderTarget::MakeWrapped(
|
||||
this, surfDesc, idDesc, rtIDDesc, cacheable, mipMapsStatus));
|
||||
this, surfDesc, idDesc, backendTex.getGLTextureParams(), rtIDDesc, cacheable,
|
||||
mipMapsStatus));
|
||||
texRT->baseLevelWasBoundToFBO();
|
||||
// We don't know what parameters are already set on wrapped textures.
|
||||
texRT->textureParamsModified();
|
||||
@ -1564,21 +1566,21 @@ static sk_sp<GrTexture> return_null_texture() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static GrGLTexture::SamplerParams set_initial_texture_params(const GrGLInterface* interface,
|
||||
const GrGLTextureInfo& info) {
|
||||
static GrGLTextureParameters::SamplerOverriddenState set_initial_texture_params(
|
||||
const GrGLInterface* interface, const GrGLTextureInfo& info) {
|
||||
// Some drivers like to know filter/wrap before seeing glTexImage2D. Some
|
||||
// drivers have a bug where an FBO won't be complete if it includes a
|
||||
// texture that is not mipmap complete (considering the filter in use).
|
||||
GrGLTexture::SamplerParams params;
|
||||
params.fMinFilter = GR_GL_NEAREST;
|
||||
params.fMagFilter = GR_GL_NEAREST;
|
||||
params.fWrapS = GR_GL_CLAMP_TO_EDGE;
|
||||
params.fWrapT = GR_GL_CLAMP_TO_EDGE;
|
||||
GR_GL_CALL(interface, TexParameteri(info.fTarget, GR_GL_TEXTURE_MAG_FILTER, params.fMagFilter));
|
||||
GR_GL_CALL(interface, TexParameteri(info.fTarget, GR_GL_TEXTURE_MIN_FILTER, params.fMinFilter));
|
||||
GR_GL_CALL(interface, TexParameteri(info.fTarget, GR_GL_TEXTURE_WRAP_S, params.fWrapS));
|
||||
GR_GL_CALL(interface, TexParameteri(info.fTarget, GR_GL_TEXTURE_WRAP_T, params.fWrapT));
|
||||
return params;
|
||||
GrGLTextureParameters::SamplerOverriddenState state;
|
||||
state.fMinFilter = GR_GL_NEAREST;
|
||||
state.fMagFilter = GR_GL_NEAREST;
|
||||
state.fWrapS = GR_GL_CLAMP_TO_EDGE;
|
||||
state.fWrapT = GR_GL_CLAMP_TO_EDGE;
|
||||
GR_GL_CALL(interface, TexParameteri(info.fTarget, GR_GL_TEXTURE_MAG_FILTER, state.fMagFilter));
|
||||
GR_GL_CALL(interface, TexParameteri(info.fTarget, GR_GL_TEXTURE_MIN_FILTER, state.fMinFilter));
|
||||
GR_GL_CALL(interface, TexParameteri(info.fTarget, GR_GL_TEXTURE_WRAP_S, state.fWrapS));
|
||||
GR_GL_CALL(interface, TexParameteri(info.fTarget, GR_GL_TEXTURE_WRAP_T, state.fWrapT));
|
||||
return state;
|
||||
}
|
||||
|
||||
size_t GLBytesPerPixel(GrGLenum glFormat) {
|
||||
@ -1654,10 +1656,10 @@ sk_sp<GrTexture> GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc,
|
||||
GrGLTexture::IDDesc idDesc;
|
||||
idDesc.fOwnership = GrBackendObjectOwnership::kOwned;
|
||||
GrMipMapsStatus mipMapsStatus;
|
||||
GrGLTexture::SamplerParams initialTexParams;
|
||||
GrGLTextureParameters::SamplerOverriddenState initialState;
|
||||
if (!this->createTextureImpl(desc, &idDesc.fInfo,
|
||||
isRenderTarget ? GrRenderable::kYes : GrRenderable::kNo,
|
||||
&initialTexParams, texels, mipLevelCount, &mipMapsStatus)) {
|
||||
&initialState, texels, mipLevelCount, &mipMapsStatus)) {
|
||||
return return_null_texture();
|
||||
}
|
||||
|
||||
@ -1677,9 +1679,9 @@ sk_sp<GrTexture> GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc,
|
||||
} else {
|
||||
tex = sk_make_sp<GrGLTexture>(this, budgeted, desc, idDesc, mipMapsStatus);
|
||||
}
|
||||
|
||||
tex->setCachedParams(&initialTexParams, tex->getCachedNonSamplerParams(),
|
||||
this->getResetTimestamp());
|
||||
// The non-sampler params are still at their default values.
|
||||
tex->parameters()->set(&initialState, GrGLTextureParameters::NonsamplerState(),
|
||||
fResetTimestampForTextureParameters);
|
||||
#ifdef TRACE_TEXTURE_CREATION
|
||||
SkDebugf("--- new texture [%d] size=(%d %d) config=%d\n",
|
||||
idDesc.fInfo.fID, desc.fWidth, desc.fHeight, desc.fConfig);
|
||||
@ -1842,7 +1844,7 @@ int GrGLGpu::getCompatibleStencilIndex(GrPixelConfig config) {
|
||||
|
||||
bool GrGLGpu::createTextureImpl(const GrSurfaceDesc& desc, GrGLTextureInfo* info,
|
||||
GrRenderable renderable,
|
||||
GrGLTexture::SamplerParams* initialTexParams,
|
||||
GrGLTextureParameters::SamplerOverriddenState* initialState,
|
||||
const GrMipLevel texels[], int mipLevelCount,
|
||||
GrMipMapsStatus* mipMapsStatus) {
|
||||
info->fID = 0;
|
||||
@ -1864,7 +1866,7 @@ bool GrGLGpu::createTextureImpl(const GrSurfaceDesc& desc, GrGLTextureInfo* info
|
||||
GR_GL_FRAMEBUFFER_ATTACHMENT));
|
||||
}
|
||||
|
||||
*initialTexParams = set_initial_texture_params(this->glInterface(), *info);
|
||||
*initialState = set_initial_texture_params(this->glInterface(), *info);
|
||||
|
||||
bool success = false;
|
||||
if (GrGLFormatIsCompressed(info->fFormat)) {
|
||||
@ -3052,71 +3054,73 @@ void GrGLGpu::bindTexture(int unitIdx, GrSamplerState samplerState, GrGLTexture*
|
||||
}
|
||||
#endif
|
||||
|
||||
ResetTimestamp timestamp = texture->getCachedParamsTimestamp();
|
||||
bool setAll = timestamp < this->getResetTimestamp();
|
||||
auto timestamp = texture->parameters()->resetTimestamp();
|
||||
bool setAll = timestamp < fResetTimestampForTextureParameters;
|
||||
|
||||
const GrGLTexture::SamplerParams* samplerParamsToRecord = nullptr;
|
||||
GrGLTexture::SamplerParams newSamplerParams;
|
||||
const GrGLTextureParameters::SamplerOverriddenState* samplerStateToRecord = nullptr;
|
||||
GrGLTextureParameters::SamplerOverriddenState newSamplerState;
|
||||
if (fSamplerObjectCache) {
|
||||
fSamplerObjectCache->bindSampler(unitIdx, samplerState);
|
||||
} else {
|
||||
const GrGLTexture::SamplerParams& oldSamplerParams = texture->getCachedSamplerParams();
|
||||
samplerParamsToRecord = &newSamplerParams;
|
||||
const GrGLTextureParameters::SamplerOverriddenState& oldSamplerState =
|
||||
texture->parameters()->samplerOverriddenState();
|
||||
samplerStateToRecord = &newSamplerState;
|
||||
|
||||
newSamplerParams.fMinFilter = filter_to_gl_min_filter(samplerState.filter());
|
||||
newSamplerParams.fMagFilter = filter_to_gl_mag_filter(samplerState.filter());
|
||||
newSamplerState.fMinFilter = filter_to_gl_min_filter(samplerState.filter());
|
||||
newSamplerState.fMagFilter = filter_to_gl_mag_filter(samplerState.filter());
|
||||
|
||||
newSamplerParams.fWrapS = wrap_mode_to_gl_wrap(samplerState.wrapModeX(), this->glCaps());
|
||||
newSamplerParams.fWrapT = wrap_mode_to_gl_wrap(samplerState.wrapModeY(), this->glCaps());
|
||||
newSamplerState.fWrapS = wrap_mode_to_gl_wrap(samplerState.wrapModeX(), this->glCaps());
|
||||
newSamplerState.fWrapT = wrap_mode_to_gl_wrap(samplerState.wrapModeY(), this->glCaps());
|
||||
|
||||
// These are the OpenGL default values.
|
||||
newSamplerParams.fMinLOD = -1000.f;
|
||||
newSamplerParams.fMaxLOD = 1000.f;
|
||||
newSamplerState.fMinLOD = -1000.f;
|
||||
newSamplerState.fMaxLOD = 1000.f;
|
||||
|
||||
if (setAll || newSamplerParams.fMagFilter != oldSamplerParams.fMagFilter) {
|
||||
if (setAll || newSamplerState.fMagFilter != oldSamplerState.fMagFilter) {
|
||||
this->setTextureUnit(unitIdx);
|
||||
GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MAG_FILTER, newSamplerParams.fMagFilter));
|
||||
GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MAG_FILTER, newSamplerState.fMagFilter));
|
||||
}
|
||||
if (setAll || newSamplerParams.fMinFilter != oldSamplerParams.fMinFilter) {
|
||||
if (setAll || newSamplerState.fMinFilter != oldSamplerState.fMinFilter) {
|
||||
this->setTextureUnit(unitIdx);
|
||||
GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MIN_FILTER, newSamplerParams.fMinFilter));
|
||||
GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MIN_FILTER, newSamplerState.fMinFilter));
|
||||
}
|
||||
if (this->glCaps().mipMapLevelAndLodControlSupport()) {
|
||||
if (setAll || newSamplerParams.fMinLOD != oldSamplerParams.fMinLOD) {
|
||||
if (setAll || newSamplerState.fMinLOD != oldSamplerState.fMinLOD) {
|
||||
this->setTextureUnit(unitIdx);
|
||||
GL_CALL(TexParameterf(target, GR_GL_TEXTURE_MIN_LOD, newSamplerParams.fMinLOD));
|
||||
GL_CALL(TexParameterf(target, GR_GL_TEXTURE_MIN_LOD, newSamplerState.fMinLOD));
|
||||
}
|
||||
if (setAll || newSamplerParams.fMaxLOD != oldSamplerParams.fMaxLOD) {
|
||||
if (setAll || newSamplerState.fMaxLOD != oldSamplerState.fMaxLOD) {
|
||||
this->setTextureUnit(unitIdx);
|
||||
GL_CALL(TexParameterf(target, GR_GL_TEXTURE_MAX_LOD, newSamplerParams.fMaxLOD));
|
||||
GL_CALL(TexParameterf(target, GR_GL_TEXTURE_MAX_LOD, newSamplerState.fMaxLOD));
|
||||
}
|
||||
}
|
||||
if (setAll || newSamplerParams.fWrapS != oldSamplerParams.fWrapS) {
|
||||
if (setAll || newSamplerState.fWrapS != oldSamplerState.fWrapS) {
|
||||
this->setTextureUnit(unitIdx);
|
||||
GL_CALL(TexParameteri(target, GR_GL_TEXTURE_WRAP_S, newSamplerParams.fWrapS));
|
||||
GL_CALL(TexParameteri(target, GR_GL_TEXTURE_WRAP_S, newSamplerState.fWrapS));
|
||||
}
|
||||
if (setAll || newSamplerParams.fWrapT != oldSamplerParams.fWrapT) {
|
||||
if (setAll || newSamplerState.fWrapT != oldSamplerState.fWrapT) {
|
||||
this->setTextureUnit(unitIdx);
|
||||
GL_CALL(TexParameteri(target, GR_GL_TEXTURE_WRAP_T, newSamplerParams.fWrapT));
|
||||
GL_CALL(TexParameteri(target, GR_GL_TEXTURE_WRAP_T, newSamplerState.fWrapT));
|
||||
}
|
||||
if (this->glCaps().clampToBorderSupport()) {
|
||||
// Make sure the border color is transparent black (the default)
|
||||
if (setAll || oldSamplerParams.fBorderColorInvalid) {
|
||||
if (setAll || oldSamplerState.fBorderColorInvalid) {
|
||||
this->setTextureUnit(unitIdx);
|
||||
static const GrGLfloat kTransparentBlack[4] = {0.f, 0.f, 0.f, 0.f};
|
||||
GL_CALL(TexParameterfv(target, GR_GL_TEXTURE_BORDER_COLOR, kTransparentBlack));
|
||||
}
|
||||
}
|
||||
}
|
||||
GrGLTexture::NonSamplerParams newNonSamplerParams;
|
||||
newNonSamplerParams.fBaseMipMapLevel = 0;
|
||||
newNonSamplerParams.fMaxMipMapLevel = texture->texturePriv().maxMipMapLevel();
|
||||
GrGLTextureParameters::NonsamplerState newNonsamplerState;
|
||||
newNonsamplerState.fBaseMipMapLevel = 0;
|
||||
newNonsamplerState.fMaxMipMapLevel = texture->texturePriv().maxMipMapLevel();
|
||||
|
||||
const GrGLTexture::NonSamplerParams& oldNonSamplerParams = texture->getCachedNonSamplerParams();
|
||||
const GrGLTextureParameters::NonsamplerState& oldNonsamplerState =
|
||||
texture->parameters()->nonsamplerState();
|
||||
if (this->glCaps().textureSwizzleSupport()) {
|
||||
auto swizzle = this->glCaps().configSwizzle(texture->config());
|
||||
newNonSamplerParams.fSwizzleKey = swizzle.asKey();
|
||||
if (setAll || swizzle.asKey() != oldNonSamplerParams.fSwizzleKey) {
|
||||
newNonsamplerState.fSwizzleKey = swizzle.asKey();
|
||||
if (setAll || swizzle.asKey() != oldNonsamplerState.fSwizzleKey) {
|
||||
GrGLenum glValues[4];
|
||||
get_gl_swizzle_values(swizzle, glValues);
|
||||
this->setTextureUnit(unitIdx);
|
||||
@ -3137,18 +3141,19 @@ void GrGLGpu::bindTexture(int unitIdx, GrSamplerState samplerState, GrGLTexture*
|
||||
if (this->glCaps().mipMapLevelAndLodControlSupport() &&
|
||||
(texture->texturePriv().textureType() != GrTextureType::kExternal ||
|
||||
!this->glCaps().dontSetBaseOrMaxLevelForExternalTextures())) {
|
||||
if (newNonSamplerParams.fBaseMipMapLevel != oldNonSamplerParams.fBaseMipMapLevel) {
|
||||
if (newNonsamplerState.fBaseMipMapLevel != oldNonsamplerState.fBaseMipMapLevel) {
|
||||
this->setTextureUnit(unitIdx);
|
||||
GL_CALL(TexParameteri(target, GR_GL_TEXTURE_BASE_LEVEL,
|
||||
newNonSamplerParams.fBaseMipMapLevel));
|
||||
newNonsamplerState.fBaseMipMapLevel));
|
||||
}
|
||||
if (newNonSamplerParams.fMaxMipMapLevel != oldNonSamplerParams.fMaxMipMapLevel) {
|
||||
if (newNonsamplerState.fMaxMipMapLevel != oldNonsamplerState.fMaxMipMapLevel) {
|
||||
this->setTextureUnit(unitIdx);
|
||||
GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MAX_LEVEL,
|
||||
newNonSamplerParams.fMaxMipMapLevel));
|
||||
newNonsamplerState.fMaxMipMapLevel));
|
||||
}
|
||||
}
|
||||
texture->setCachedParams(samplerParamsToRecord, newNonSamplerParams, this->getResetTimestamp());
|
||||
texture->parameters()->set(samplerStateToRecord, newNonsamplerState,
|
||||
fResetTimestampForTextureParameters);
|
||||
}
|
||||
|
||||
void GrGLGpu::onResetTextureBindings() {
|
||||
@ -3952,9 +3957,10 @@ bool GrGLGpu::onRegenerateMipMapLevels(GrTexture* texture) {
|
||||
GR_GL_TEXTURE_2D, 0, 0));
|
||||
|
||||
// We modified the base level param.
|
||||
GrGLTexture::NonSamplerParams params = glTex->getCachedNonSamplerParams();
|
||||
params.fBaseMipMapLevel = levelCount - 2; // we drew the 2nd to last level into the last level.
|
||||
glTex->setCachedParams(nullptr, params, this->getResetTimestamp());
|
||||
GrGLTextureParameters::NonsamplerState nonsamplerState = glTex->parameters()->nonsamplerState();
|
||||
// We drew the 2nd to last level into the last level.
|
||||
nonsamplerState.fBaseMipMapLevel = levelCount - 2;
|
||||
glTex->parameters()->set(nullptr, nonsamplerState, fResetTimestampForTextureParameters);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -4146,17 +4152,20 @@ GrBackendTexture GrGLGpu::createBackendTexture(int w, int h,
|
||||
desc.fConfig = config;
|
||||
|
||||
GrGLTextureInfo info;
|
||||
GrGLTexture::SamplerParams initialTexParams;
|
||||
GrGLTextureParameters::SamplerOverriddenState initialState;
|
||||
|
||||
if (!this->createTextureImpl(desc, &info, renderable, &initialTexParams,
|
||||
texels.get(), mipLevelCount, nullptr)) {
|
||||
if (!this->createTextureImpl(desc, &info, renderable, &initialState, texels.get(),
|
||||
mipLevelCount, nullptr)) {
|
||||
return GrBackendTexture(); // invalid
|
||||
}
|
||||
|
||||
// unbind the texture from the texture unit to avoid asserts
|
||||
GL_CALL(BindTexture(info.fTarget, 0));
|
||||
|
||||
GrBackendTexture beTex = GrBackendTexture(w, h, mipMapped, info);
|
||||
auto parameters = sk_make_sp<GrGLTextureParameters>();
|
||||
parameters->set(&initialState, GrGLTextureParameters::NonsamplerState(),
|
||||
fResetTimestampForTextureParameters);
|
||||
GrBackendTexture beTex = GrBackendTexture(w, h, mipMapped, info, std::move(parameters));
|
||||
#if GR_TEST_UTILS
|
||||
// Lots of tests don't go through Skia's public interface, which will set the config, so for
|
||||
// testing we make sure we set a config here.
|
||||
|
@ -216,8 +216,9 @@ private:
|
||||
// The texture is populated with |texels|, if it exists.
|
||||
// The texture parameters are cached in |initialTexParams|.
|
||||
bool createTextureImpl(const GrSurfaceDesc& desc, GrGLTextureInfo* info, GrRenderable,
|
||||
GrGLTexture::SamplerParams* initialTexParams, const GrMipLevel texels[],
|
||||
int mipLevelCount, GrMipMapsStatus* mipMapsStatus);
|
||||
GrGLTextureParameters::SamplerOverriddenState* initialState,
|
||||
const GrMipLevel texels[], int mipLevelCount,
|
||||
GrMipMapsStatus* mipMapsStatus);
|
||||
|
||||
// Checks whether glReadPixels can be called to get pixel values in readConfig from the
|
||||
// render target.
|
||||
@ -665,6 +666,8 @@ private:
|
||||
|
||||
GrPrimitiveType fLastPrimitiveType;
|
||||
|
||||
GrGLTextureParameters::ResetTimestamp fResetTimestampForTextureParameters = 0;
|
||||
|
||||
class SamplerObjectCache;
|
||||
std::unique_ptr<SamplerObjectCache> fSamplerObjectCache;
|
||||
|
||||
|
@ -45,7 +45,8 @@ static inline GrGLenum target_from_texture_type(GrTextureType type) {
|
||||
GrGLTexture::GrGLTexture(GrGLGpu* gpu, SkBudgeted budgeted, const GrSurfaceDesc& desc,
|
||||
const IDDesc& idDesc, GrMipMapsStatus mipMapsStatus)
|
||||
: GrSurface(gpu, desc)
|
||||
, INHERITED(gpu, desc, TextureTypeFromTarget(idDesc.fInfo.fTarget), mipMapsStatus) {
|
||||
, INHERITED(gpu, desc, TextureTypeFromTarget(idDesc.fInfo.fTarget), mipMapsStatus)
|
||||
, fParameters(sk_make_sp<GrGLTextureParameters>()) {
|
||||
this->init(desc, idDesc);
|
||||
this->registerWithCache(budgeted);
|
||||
if (GrPixelConfigIsCompressed(desc.fConfig)) {
|
||||
@ -54,9 +55,12 @@ GrGLTexture::GrGLTexture(GrGLGpu* gpu, SkBudgeted budgeted, const GrSurfaceDesc&
|
||||
}
|
||||
|
||||
GrGLTexture::GrGLTexture(GrGLGpu* gpu, const GrSurfaceDesc& desc, GrMipMapsStatus mipMapsStatus,
|
||||
const IDDesc& idDesc, GrWrapCacheable cacheable, GrIOType ioType)
|
||||
const IDDesc& idDesc, sk_sp<GrGLTextureParameters> parameters,
|
||||
GrWrapCacheable cacheable, GrIOType ioType)
|
||||
: GrSurface(gpu, desc)
|
||||
, INHERITED(gpu, desc, TextureTypeFromTarget(idDesc.fInfo.fTarget), mipMapsStatus) {
|
||||
, INHERITED(gpu, desc, TextureTypeFromTarget(idDesc.fInfo.fTarget), mipMapsStatus)
|
||||
, fParameters(std::move(parameters)) {
|
||||
SkASSERT(fParameters);
|
||||
this->init(desc, idDesc);
|
||||
this->registerWithCacheWrapped(cacheable);
|
||||
if (ioType == kRead_GrIOType) {
|
||||
@ -65,16 +69,17 @@ GrGLTexture::GrGLTexture(GrGLGpu* gpu, const GrSurfaceDesc& desc, GrMipMapsStatu
|
||||
}
|
||||
|
||||
GrGLTexture::GrGLTexture(GrGLGpu* gpu, const GrSurfaceDesc& desc, const IDDesc& idDesc,
|
||||
GrMipMapsStatus mipMapsStatus)
|
||||
sk_sp<GrGLTextureParameters> parameters, GrMipMapsStatus mipMapsStatus)
|
||||
: GrSurface(gpu, desc)
|
||||
, INHERITED(gpu, desc, TextureTypeFromTarget(idDesc.fInfo.fTarget), mipMapsStatus) {
|
||||
SkASSERT(parameters || idDesc.fOwnership == GrBackendObjectOwnership::kOwned);
|
||||
fParameters = parameters ? std::move(parameters) : sk_make_sp<GrGLTextureParameters>();
|
||||
this->init(desc, idDesc);
|
||||
}
|
||||
|
||||
void GrGLTexture::init(const GrSurfaceDesc& desc, const IDDesc& idDesc) {
|
||||
SkASSERT(0 != idDesc.fInfo.fID);
|
||||
SkASSERT(0 != idDesc.fInfo.fFormat);
|
||||
fParamsTimestamp = GrGpu::kExpiredTimestamp;
|
||||
fID = idDesc.fInfo.fID;
|
||||
fFormat = idDesc.fInfo.fFormat;
|
||||
fTextureIDOwnership = idDesc.fOwnership;
|
||||
@ -104,7 +109,8 @@ GrBackendTexture GrGLTexture::getBackendTexture() const {
|
||||
info.fTarget = target_from_texture_type(this->texturePriv().textureType());
|
||||
info.fID = fID;
|
||||
info.fFormat = fFormat;
|
||||
return GrBackendTexture(this->width(), this->height(), this->texturePriv().mipMapped(), info);
|
||||
return GrBackendTexture(this->width(), this->height(), this->texturePriv().mipMapped(), info,
|
||||
fParameters);
|
||||
}
|
||||
|
||||
GrBackendFormat GrGLTexture::backendFormat() const {
|
||||
@ -114,8 +120,10 @@ GrBackendFormat GrGLTexture::backendFormat() const {
|
||||
|
||||
sk_sp<GrGLTexture> GrGLTexture::MakeWrapped(GrGLGpu* gpu, const GrSurfaceDesc& desc,
|
||||
GrMipMapsStatus mipMapsStatus, const IDDesc& idDesc,
|
||||
sk_sp<GrGLTextureParameters> parameters,
|
||||
GrWrapCacheable cacheable, GrIOType ioType) {
|
||||
return sk_sp<GrGLTexture>(new GrGLTexture(gpu, desc, mipMapsStatus, idDesc, cacheable, ioType));
|
||||
return sk_sp<GrGLTexture>(new GrGLTexture(gpu, desc, mipMapsStatus, idDesc,
|
||||
std::move(parameters), cacheable, ioType));
|
||||
}
|
||||
|
||||
bool GrGLTexture::onStealBackendTexture(GrBackendTexture* backendTexture,
|
||||
|
@ -10,6 +10,7 @@
|
||||
#define GrGLTexture_DEFINED
|
||||
|
||||
#include "include/gpu/GrTexture.h"
|
||||
#include "include/private/GrGLTypesPriv.h"
|
||||
#include "src/gpu/GrGpu.h"
|
||||
#include "src/gpu/gl/GrGLUtil.h"
|
||||
|
||||
@ -17,44 +18,6 @@ class GrGLGpu;
|
||||
|
||||
class GrGLTexture : public GrTexture {
|
||||
public:
|
||||
// Texture state that overlaps with sampler object state. We don't need to track this if we
|
||||
// are using sampler objects.
|
||||
struct SamplerParams {
|
||||
// These are the OpenGL defaults.
|
||||
GrGLenum fMinFilter = GR_GL_NEAREST_MIPMAP_LINEAR;
|
||||
GrGLenum fMagFilter = GR_GL_LINEAR;
|
||||
GrGLenum fWrapS = GR_GL_REPEAT;
|
||||
GrGLenum fWrapT = GR_GL_REPEAT;
|
||||
GrGLfloat fMinLOD = -1000.f;
|
||||
GrGLfloat fMaxLOD = 1000.f;
|
||||
// We always want the border color to be transparent black, so no need to store 4 floats.
|
||||
// Just track if it's been invalidated and no longer the default
|
||||
bool fBorderColorInvalid = false;
|
||||
|
||||
void invalidate() {
|
||||
fMinFilter = ~0U;
|
||||
fMagFilter = ~0U;
|
||||
fWrapS = ~0U;
|
||||
fWrapT = ~0U;
|
||||
fMinLOD = SK_ScalarNaN;
|
||||
fMaxLOD = SK_ScalarNaN;
|
||||
fBorderColorInvalid = true;
|
||||
}
|
||||
};
|
||||
|
||||
// Texture state that does not overlap with sampler object state.
|
||||
struct NonSamplerParams {
|
||||
// These are the OpenGL defaults.
|
||||
uint32_t fSwizzleKey = GrSwizzle::RGBA().asKey();
|
||||
GrGLint fBaseMipMapLevel = 0;
|
||||
GrGLint fMaxMipMapLevel = 1000;
|
||||
void invalidate() {
|
||||
fSwizzleKey = ~0U;
|
||||
fBaseMipMapLevel = ~0;
|
||||
fMaxMipMapLevel = ~0;
|
||||
}
|
||||
};
|
||||
|
||||
struct IDDesc {
|
||||
GrGLTextureInfo fInfo;
|
||||
GrBackendObjectOwnership fOwnership;
|
||||
@ -70,25 +33,10 @@ public:
|
||||
|
||||
GrBackendFormat backendFormat() const override;
|
||||
|
||||
void textureParamsModified() override {
|
||||
fSamplerParams.invalidate();
|
||||
fNonSamplerParams.invalidate();
|
||||
}
|
||||
// TODO: Remove once clients are no longer calling this.
|
||||
void textureParamsModified() override { fParameters->invalidate(); }
|
||||
|
||||
// These functions are used to track the texture parameters associated with the texture.
|
||||
GrGpu::ResetTimestamp getCachedParamsTimestamp() const { return fParamsTimestamp; }
|
||||
const SamplerParams& getCachedSamplerParams() const { return fSamplerParams; }
|
||||
const NonSamplerParams& getCachedNonSamplerParams() const { return fNonSamplerParams; }
|
||||
|
||||
void setCachedParams(const SamplerParams* samplerParams,
|
||||
const NonSamplerParams& nonSamplerParams,
|
||||
GrGpu::ResetTimestamp currTimestamp) {
|
||||
if (samplerParams) {
|
||||
fSamplerParams = *samplerParams;
|
||||
}
|
||||
fNonSamplerParams = nonSamplerParams;
|
||||
fParamsTimestamp = currTimestamp;
|
||||
}
|
||||
GrGLTextureParameters* parameters() { return fParameters.get(); }
|
||||
|
||||
GrGLuint textureID() const { return fID; }
|
||||
|
||||
@ -98,17 +46,19 @@ public:
|
||||
void baseLevelWasBoundToFBO() { fBaseLevelHasBeenBoundToFBO = true; }
|
||||
|
||||
static sk_sp<GrGLTexture> MakeWrapped(GrGLGpu*, const GrSurfaceDesc&, GrMipMapsStatus,
|
||||
const IDDesc&, GrWrapCacheable, GrIOType);
|
||||
const IDDesc&, sk_sp<GrGLTextureParameters>,
|
||||
GrWrapCacheable, GrIOType);
|
||||
|
||||
void dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const override;
|
||||
|
||||
protected:
|
||||
// Constructor for subclasses.
|
||||
GrGLTexture(GrGLGpu*, const GrSurfaceDesc&, const IDDesc&, GrMipMapsStatus);
|
||||
GrGLTexture(GrGLGpu*, const GrSurfaceDesc&, const IDDesc&, sk_sp<GrGLTextureParameters>,
|
||||
GrMipMapsStatus);
|
||||
|
||||
// Constructor for instances wrapping backend objects.
|
||||
GrGLTexture(GrGLGpu*, const GrSurfaceDesc&, GrMipMapsStatus, const IDDesc&, GrWrapCacheable,
|
||||
GrIOType);
|
||||
GrGLTexture(GrGLGpu*, const GrSurfaceDesc&, GrMipMapsStatus, const IDDesc&,
|
||||
sk_sp<GrGLTextureParameters>, GrWrapCacheable, GrIOType);
|
||||
|
||||
void init(const GrSurfaceDesc&, const IDDesc&);
|
||||
|
||||
@ -118,9 +68,7 @@ protected:
|
||||
bool onStealBackendTexture(GrBackendTexture*, SkImage::BackendTextureReleaseProc*) override;
|
||||
|
||||
private:
|
||||
SamplerParams fSamplerParams;
|
||||
NonSamplerParams fNonSamplerParams;
|
||||
GrGpu::ResetTimestamp fParamsTimestamp;
|
||||
sk_sp<GrGLTextureParameters> fParameters;
|
||||
GrGLuint fID;
|
||||
GrGLenum fFormat;
|
||||
GrBackendObjectOwnership fTextureIDOwnership;
|
||||
|
@ -19,7 +19,7 @@ GrGLTextureRenderTarget::GrGLTextureRenderTarget(GrGLGpu* gpu,
|
||||
const GrGLRenderTarget::IDDesc& rtIDDesc,
|
||||
GrMipMapsStatus mipMapsStatus)
|
||||
: GrSurface(gpu, desc)
|
||||
, GrGLTexture(gpu, desc, texIDDesc, mipMapsStatus)
|
||||
, GrGLTexture(gpu, desc, texIDDesc, nullptr, mipMapsStatus)
|
||||
, GrGLRenderTarget(gpu, desc, texIDDesc.fInfo.fFormat, rtIDDesc) {
|
||||
this->registerWithCache(budgeted);
|
||||
}
|
||||
@ -27,11 +27,12 @@ GrGLTextureRenderTarget::GrGLTextureRenderTarget(GrGLGpu* gpu,
|
||||
GrGLTextureRenderTarget::GrGLTextureRenderTarget(GrGLGpu* gpu,
|
||||
const GrSurfaceDesc& desc,
|
||||
const GrGLTexture::IDDesc& texIDDesc,
|
||||
sk_sp<GrGLTextureParameters> parameters,
|
||||
const GrGLRenderTarget::IDDesc& rtIDDesc,
|
||||
GrWrapCacheable cacheable,
|
||||
GrMipMapsStatus mipMapsStatus)
|
||||
: GrSurface(gpu, desc)
|
||||
, GrGLTexture(gpu, desc, texIDDesc, mipMapsStatus)
|
||||
, GrGLTexture(gpu, desc, texIDDesc, std::move(parameters), mipMapsStatus)
|
||||
, GrGLRenderTarget(gpu, desc, texIDDesc.fInfo.fFormat, rtIDDesc) {
|
||||
this->registerWithCacheWrapped(cacheable);
|
||||
}
|
||||
@ -58,14 +59,13 @@ bool GrGLTextureRenderTarget::canAttemptStencilAttachment() const {
|
||||
|
||||
sk_sp<GrGLTextureRenderTarget> GrGLTextureRenderTarget::MakeWrapped(
|
||||
GrGLGpu* gpu, const GrSurfaceDesc& desc, const GrGLTexture::IDDesc& texIDDesc,
|
||||
const GrGLRenderTarget::IDDesc& rtIDDesc, GrWrapCacheable cacheable,
|
||||
GrMipMapsStatus mipMapsStatus) {
|
||||
return sk_sp<GrGLTextureRenderTarget>(
|
||||
new GrGLTextureRenderTarget(gpu, desc, texIDDesc, rtIDDesc, cacheable, mipMapsStatus));
|
||||
sk_sp<GrGLTextureParameters> parameters, const GrGLRenderTarget::IDDesc& rtIDDesc,
|
||||
GrWrapCacheable cacheable, GrMipMapsStatus mipMapsStatus) {
|
||||
return sk_sp<GrGLTextureRenderTarget>(new GrGLTextureRenderTarget(
|
||||
gpu, desc, texIDDesc, std::move(parameters), rtIDDesc, cacheable, mipMapsStatus));
|
||||
}
|
||||
|
||||
size_t GrGLTextureRenderTarget::onGpuMemorySize() const {
|
||||
return GrSurface::ComputeSize(this->config(), this->width(), this->height(),
|
||||
this->numSamplesOwnedPerPixel(),
|
||||
this->texturePriv().mipMapped());
|
||||
this->numSamplesOwnedPerPixel(), this->texturePriv().mipMapped());
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ public:
|
||||
|
||||
static sk_sp<GrGLTextureRenderTarget> MakeWrapped(GrGLGpu* gpu, const GrSurfaceDesc& desc,
|
||||
const GrGLTexture::IDDesc& texIDDesc,
|
||||
sk_sp<GrGLTextureParameters> parameters,
|
||||
const GrGLRenderTarget::IDDesc& rtIDDesc,
|
||||
GrWrapCacheable cacheble, GrMipMapsStatus);
|
||||
|
||||
@ -61,6 +62,7 @@ private:
|
||||
GrGLTextureRenderTarget(GrGLGpu* gpu,
|
||||
const GrSurfaceDesc& desc,
|
||||
const GrGLTexture::IDDesc& texIDDesc,
|
||||
sk_sp<GrGLTextureParameters> parameters,
|
||||
const GrGLRenderTarget::IDDesc& rtIDDesc,
|
||||
GrWrapCacheable,
|
||||
GrMipMapsStatus);
|
||||
|
67
src/gpu/gl/GrGLTypesPriv.cpp
Normal file
67
src/gpu/gl/GrGLTypesPriv.cpp
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2019 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "include/private/GrGLTypesPriv.h"
|
||||
#include "include/core/SkScalar.h"
|
||||
#include "src/gpu/GrSwizzle.h"
|
||||
#include "src/gpu/gl/GrGLDefines.h"
|
||||
|
||||
GrGLTextureParameters::SamplerOverriddenState::SamplerOverriddenState()
|
||||
// These are the OpenGL defaults.
|
||||
: fMinFilter(GR_GL_NEAREST_MIPMAP_LINEAR)
|
||||
, fMagFilter(GR_GL_LINEAR)
|
||||
, fWrapS(GR_GL_REPEAT)
|
||||
, fWrapT(GR_GL_REPEAT)
|
||||
, fMinLOD(-1000.f)
|
||||
, fMaxLOD(1000.f)
|
||||
, fBorderColorInvalid(false) {}
|
||||
|
||||
void GrGLTextureParameters::SamplerOverriddenState::invalidate() {
|
||||
fMinFilter = ~0U;
|
||||
fMagFilter = ~0U;
|
||||
fWrapS = ~0U;
|
||||
fWrapT = ~0U;
|
||||
fMinLOD = SK_ScalarNaN;
|
||||
fMaxLOD = SK_ScalarNaN;
|
||||
fBorderColorInvalid = true;
|
||||
}
|
||||
|
||||
GrGLTextureParameters::NonsamplerState::NonsamplerState()
|
||||
// These are the OpenGL defaults.
|
||||
: fSwizzleKey(GrSwizzle::RGBA().asKey()), fBaseMipMapLevel(0), fMaxMipMapLevel(1000) {}
|
||||
|
||||
void GrGLTextureParameters::NonsamplerState::invalidate() {
|
||||
fSwizzleKey = ~0U;
|
||||
fBaseMipMapLevel = ~0;
|
||||
fMaxMipMapLevel = ~0;
|
||||
}
|
||||
|
||||
void GrGLTextureParameters::invalidate() {
|
||||
fSamplerOverriddenState.invalidate();
|
||||
fNonsamplerState.invalidate();
|
||||
}
|
||||
|
||||
void GrGLTextureParameters::set(const SamplerOverriddenState* samplerState,
|
||||
const NonsamplerState& nonsamplerState,
|
||||
ResetTimestamp currTimestamp) {
|
||||
if (samplerState) {
|
||||
fSamplerOverriddenState = *samplerState;
|
||||
}
|
||||
fNonsamplerState = nonsamplerState;
|
||||
fResetTimestamp = currTimestamp;
|
||||
}
|
||||
|
||||
void GrGLBackendTextureInfo::assign(const GrGLBackendTextureInfo& that, bool thisIsValid) {
|
||||
fInfo = that.fInfo;
|
||||
SkSafeRef(that.fParams);
|
||||
if (thisIsValid) {
|
||||
SkSafeUnref(fParams);
|
||||
}
|
||||
fParams = that.fParams;
|
||||
}
|
||||
|
||||
void GrGLBackendTextureInfo::cleanup() { SkSafeUnref(fParams); }
|
134
tests/GLBackendSurfaceTest.cpp
Normal file
134
tests/GLBackendSurfaceTest.cpp
Normal file
@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright 2019 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "include/core/SkTypes.h"
|
||||
|
||||
#ifdef SK_GL
|
||||
|
||||
#include "tests/Test.h"
|
||||
|
||||
#include "include/core/SkImage.h"
|
||||
#include "include/core/SkSurface.h"
|
||||
#include "include/gpu/GrBackendSurface.h"
|
||||
#include "include/gpu/GrTexture.h"
|
||||
#include "include/gpu/gl/GrGLTypes.h"
|
||||
#include "include/private/GrGLTypesPriv.h"
|
||||
#include "include/private/GrTextureProxy.h"
|
||||
#include "src/gpu/GrContextPriv.h"
|
||||
#include "src/gpu/gl/GrGLCaps.h"
|
||||
#include "src/gpu/gl/GrGLTexture.h"
|
||||
#include "src/image/SkImage_Base.h"
|
||||
|
||||
static bool sampler_params_invalid(const GrGLTextureParameters& parameters) {
|
||||
return SkScalarIsNaN(parameters.samplerOverriddenState().fMaxLOD);
|
||||
}
|
||||
|
||||
static bool nonsampler_params_invalid(const GrGLTextureParameters& parameters) {
|
||||
GrGLTextureParameters::NonsamplerState invalidNSState;
|
||||
invalidNSState.invalidate();
|
||||
return 0 == memcmp(¶meters.nonsamplerState(), &invalidNSState, sizeof(invalidNSState));
|
||||
}
|
||||
|
||||
static bool params_invalid(const GrGLTextureParameters& parameters) {
|
||||
return sampler_params_invalid(parameters) && nonsampler_params_invalid(parameters);
|
||||
}
|
||||
|
||||
static bool params_valid(const GrGLTextureParameters& parameters, const GrGLCaps* caps) {
|
||||
if (nonsampler_params_invalid(parameters)) {
|
||||
return false;
|
||||
}
|
||||
// We should only set the sampler parameters to valid if we don't have sampler object support.
|
||||
return caps->samplerObjectSupport() == sampler_params_invalid(parameters);
|
||||
}
|
||||
|
||||
DEF_GPUTEST_FOR_ALL_GL_CONTEXTS(GLTextureParameters, reporter, ctxInfo) {
|
||||
GrContext* context = ctxInfo.grContext();
|
||||
|
||||
GrBackendTexture backendTex = context->createBackendTexture(
|
||||
1, 1, kRGBA_8888_SkColorType, GrMipMapped::kNo, GrRenderable::kNo);
|
||||
REPORTER_ASSERT(reporter, backendTex.isValid());
|
||||
|
||||
GrGLTextureInfo info;
|
||||
REPORTER_ASSERT(reporter, backendTex.getGLTextureInfo(&info));
|
||||
|
||||
GrBackendTexture backendTexCopy = backendTex;
|
||||
REPORTER_ASSERT(reporter, backendTexCopy.isSameTexture(backendTex));
|
||||
|
||||
sk_sp<SkImage> wrappedImage =
|
||||
SkImage::MakeFromTexture(context, backendTex, kTopLeft_GrSurfaceOrigin,
|
||||
kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
|
||||
REPORTER_ASSERT(reporter, wrappedImage);
|
||||
|
||||
sk_sp<GrTextureProxy> texProxy = as_IB(wrappedImage)->asTextureProxyRef(context);
|
||||
REPORTER_ASSERT(reporter, texProxy.get());
|
||||
REPORTER_ASSERT(reporter, texProxy->isInstantiated());
|
||||
auto texture = static_cast<GrGLTexture*>(texProxy->peekTexture());
|
||||
REPORTER_ASSERT(reporter, texture);
|
||||
auto parameters = texture->parameters();
|
||||
REPORTER_ASSERT(reporter, parameters);
|
||||
GrGLTextureParameters::SamplerOverriddenState invalidSState;
|
||||
invalidSState.invalidate();
|
||||
GrGLTextureParameters::NonsamplerState invalidNSState;
|
||||
invalidNSState.invalidate();
|
||||
|
||||
// After wrapping we should assume the client's texture can be in any state.
|
||||
REPORTER_ASSERT(reporter, params_invalid(*parameters));
|
||||
|
||||
auto surf = SkSurface::MakeRenderTarget(
|
||||
context, SkBudgeted::kYes,
|
||||
SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kPremul_SkAlphaType), 1, nullptr);
|
||||
REPORTER_ASSERT(reporter, surf);
|
||||
surf->getCanvas()->drawImage(wrappedImage, 0, 0);
|
||||
surf->flush();
|
||||
|
||||
auto caps = static_cast<const GrGLCaps*>(context->priv().caps());
|
||||
// Now the texture should be in a known state.
|
||||
REPORTER_ASSERT(reporter, params_valid(*parameters, caps));
|
||||
|
||||
// Test invalidating from the GL backend texture.
|
||||
backendTex.glTextureParametersModified();
|
||||
REPORTER_ASSERT(reporter, params_invalid(*parameters));
|
||||
|
||||
REPORTER_ASSERT(reporter, surf);
|
||||
surf->getCanvas()->drawImage(wrappedImage, 0, 0);
|
||||
surf->flush();
|
||||
REPORTER_ASSERT(reporter, params_valid(*parameters, caps));
|
||||
|
||||
// Test invalidating from the copy.
|
||||
backendTexCopy.glTextureParametersModified();
|
||||
REPORTER_ASSERT(reporter, params_invalid(*parameters));
|
||||
|
||||
// Check that we can do things like assigning the backend texture to invalid one, assign an
|
||||
// invalid one, assin a backend texture to inself etc. Success here is that we don't hit any of
|
||||
// our ref counting asserts.
|
||||
REPORTER_ASSERT(reporter, GrBackendTexture::TestingOnly_Equals(backendTex, backendTexCopy));
|
||||
|
||||
GrBackendTexture invalidTexture;
|
||||
REPORTER_ASSERT(reporter, !invalidTexture.isValid());
|
||||
REPORTER_ASSERT(reporter,
|
||||
!GrBackendTexture::TestingOnly_Equals(invalidTexture, backendTexCopy));
|
||||
|
||||
backendTexCopy = invalidTexture;
|
||||
REPORTER_ASSERT(reporter, !backendTexCopy.isValid());
|
||||
REPORTER_ASSERT(reporter,
|
||||
!GrBackendTexture::TestingOnly_Equals(invalidTexture, backendTexCopy));
|
||||
|
||||
invalidTexture = backendTex;
|
||||
REPORTER_ASSERT(reporter, invalidTexture.isValid());
|
||||
REPORTER_ASSERT(reporter, GrBackendTexture::TestingOnly_Equals(invalidTexture, backendTex));
|
||||
|
||||
invalidTexture = static_cast<decltype(invalidTexture)&>(invalidTexture);
|
||||
REPORTER_ASSERT(reporter, invalidTexture.isValid());
|
||||
REPORTER_ASSERT(reporter, GrBackendTexture::TestingOnly_Equals(invalidTexture, invalidTexture));
|
||||
|
||||
wrappedImage.reset();
|
||||
GrFlushInfo flushInfo;
|
||||
flushInfo.fFlags = kSyncCpu_GrFlushFlag;
|
||||
context->flush(flushInfo);
|
||||
context->deleteBackendTexture(backendTex);
|
||||
}
|
||||
#endif
|
@ -127,8 +127,11 @@ DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SkTraceMemoryDump_unownedGLTexture, report
|
||||
idDesc.fInfo = glInfo;
|
||||
idDesc.fOwnership = GrBackendObjectOwnership::kBorrowed;
|
||||
|
||||
auto texture = GrGLTexture::MakeWrapped(gpu, desc, GrMipMapsStatus::kNotAllocated, idDesc,
|
||||
GrWrapCacheable::kNo, kRead_GrIOType);
|
||||
auto params = sk_make_sp<GrGLTextureParameters>();
|
||||
|
||||
auto texture =
|
||||
GrGLTexture::MakeWrapped(gpu, desc, GrMipMapsStatus::kNotAllocated, idDesc,
|
||||
std::move(params), GrWrapCacheable::kNo, kRead_GrIOType);
|
||||
|
||||
ValidateMemoryDumps(reporter, context, texture->gpuMemorySize(), false /* isOwned */);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user