aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--docs/SkSurface_Reference.bmh25
-rw-r--r--include/core/SkSurface.h12
-rw-r--r--src/gpu/GrContext.cpp16
-rw-r--r--src/image/SkSurface.cpp5
-rw-r--r--src/image/SkSurface_Gpu.cpp20
-rw-r--r--tests/DeferredDisplayListTest.cpp49
6 files changed, 118 insertions, 9 deletions
diff --git a/docs/SkSurface_Reference.bmh b/docs/SkSurface_Reference.bmh
index a7053f69d3..e37ac57250 100644
--- a/docs/SkSurface_Reference.bmh
+++ b/docs/SkSurface_Reference.bmh
@@ -711,6 +711,31 @@ Surface bottom-left corner is pinned to the origin.
# ------------------------------------------------------------------------------
+#Method static sk_sp<SkSurface> MakeRenderTarget(GrContext* context,
+ const SkSurfaceCharacterization& characterization,
+ SkBudgeted budgeted)
+
+Returns SkSurface on GPU indicated by context that is compatible with the provided
+characterization. budgeted selects whether allocation for pixels is tracked by context.
+
+ @param context GPU context
+ @param characterization description of the desired SkSurface
+ @param budgeted one of: SkBudgeted::kNo, SkBudgeted::kYes
+ @return SkSurface if all parameters are valid; otherwise, nullptr
+
+#Param context GPU_Context ##
+#Param characterization description of the desired SkSurface ##
+#Param budgeted one of: SkBudgeted::kNo, SkBudgeted::kYes
+##
+
+#Return Surface if all parameters are valid; otherwise, nullptr ##
+
+#SeeAlso MakeFromBackendRenderTarget MakeFromBackendTextureAsRenderTarget
+
+#Method ##
+
+# ------------------------------------------------------------------------------
+
#Method static sk_sp<SkSurface> MakeNull(int width, int height)
#In Constructor
diff --git a/include/core/SkSurface.h b/include/core/SkSurface.h
index 419e548f48..28b830dc27 100644
--- a/include/core/SkSurface.h
+++ b/include/core/SkSurface.h
@@ -335,6 +335,18 @@ public:
nullptr);
}
+ /** Returns SkSurface on GPU indicated by context that is compatible with the provided
+ characterization. budgeted selects whether allocation for pixels is tracked by context.
+
+ @param context GPU context
+ @param characterization description of the desired SkSurface
+ @param budgeted one of: SkBudgeted::kNo, SkBudgeted::kYes
+ @return SkSurface if all parameters are valid; otherwise, nullptr
+ */
+ static sk_sp<SkSurface> MakeRenderTarget(GrContext* context,
+ const SkSurfaceCharacterization& characterization,
+ SkBudgeted budgeted);
+
/** Returns SkSurface without backing pixels. Drawing to SkCanvas returned from SkSurface
has no effect. Calling makeImageSnapshot() on returned SkSurface returns nullptr.
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index db13931b2b..1112b5705f 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -33,6 +33,7 @@
#include "SkImageInfoPriv.h"
#include "SkJSONWriter.h"
#include "SkMakeUnique.h"
+#include "SkSurface_Gpu.h"
#include "SkTaskGroup.h"
#include "SkUnPreMultiplyPriv.h"
#include "effects/GrConfigConversionEffect.h"
@@ -172,8 +173,9 @@ SkSurfaceCharacterization GrContextThreadSafeProxy::createCharacterization(
return SkSurfaceCharacterization(); // return an invalid characterization
}
- // We're assuming GrFSAAType::kMixedSamples will never be specified via this code path
- GrFSAAType FSAAType = sampleCnt > 1 ? GrFSAAType::kUnifiedMSAA : GrFSAAType::kNone;
+ if (!SkSurface_Gpu::Valid(ii)) {
+ return SkSurfaceCharacterization(); // return an invalid characterization
+ }
if (!fCaps->mipMapSupport()) {
isMipMapped = false;
@@ -184,6 +186,16 @@ SkSurfaceCharacterization GrContextThreadSafeProxy::createCharacterization(
return SkSurfaceCharacterization(); // return an invalid characterization
}
+ sampleCnt = fCaps->getRenderTargetSampleCount(sampleCnt, config);
+ if (!sampleCnt) {
+ return SkSurfaceCharacterization(); // return an invalid characterization
+ }
+
+ GrFSAAType FSAAType = GrFSAAType::kNone;
+ if (sampleCnt > 1) {
+ FSAAType = fCaps->usesMixedSamples() ? GrFSAAType::kMixedSamples : GrFSAAType::kUnifiedMSAA;
+ }
+
// This surface characterization factory assumes that the resulting characterization is
// textureable.
if (!fCaps->isConfigTexturable(config)) {
diff --git a/src/image/SkSurface.cpp b/src/image/SkSurface.cpp
index 30a1fa464c..9444de7724 100644
--- a/src/image/SkSurface.cpp
+++ b/src/image/SkSurface.cpp
@@ -277,6 +277,11 @@ sk_sp<SkSurface> SkSurface::MakeRenderTarget(GrContext*, SkBudgeted, const SkIma
return nullptr;
}
+sk_sp<SkSurface> SkSurface::MakeRenderTarget(GrContext*, const SkSurfaceCharacterization&,
+ SkBudgeted) {
+ return nullptr;
+}
+
sk_sp<SkSurface> SkSurface::MakeFromBackendTexture(GrContext*, const GrBackendTexture&,
GrSurfaceOrigin origin, int sampleCnt,
SkColorType, sk_sp<SkColorSpace>,
diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp
index ace1981bf7..bc5fe68940 100644
--- a/src/image/SkSurface_Gpu.cpp
+++ b/src/image/SkSurface_Gpu.cpp
@@ -269,6 +269,26 @@ bool SkSurface_Gpu::Valid(GrContext* context, GrPixelConfig config, SkColorSpace
}
}
+sk_sp<SkSurface> SkSurface::MakeRenderTarget(GrContext* context,
+ const SkSurfaceCharacterization& c,
+ SkBudgeted budgeted) {
+ if (!c.isValid()) {
+ return nullptr;
+ }
+
+ SkColorType ct;
+ if (!GrPixelConfigToColorType(c.config(), &ct)) {
+ return nullptr;
+ }
+
+ SkImageInfo ii = SkImageInfo::Make(c.width(), c.height(), ct, kPremul_SkAlphaType,
+ c.refColorSpace());
+
+ return MakeRenderTarget(context, budgeted, ii, c.stencilCount(), c.origin(),
+ &c.surfaceProps(), c.isMipMapped());
+}
+
+
sk_sp<SkSurface> SkSurface::MakeRenderTarget(GrContext* ctx, SkBudgeted budgeted,
const SkImageInfo& info, int sampleCount,
GrSurfaceOrigin origin, const SkSurfaceProps* props,
diff --git a/tests/DeferredDisplayListTest.cpp b/tests/DeferredDisplayListTest.cpp
index d9aa522125..ddbb4a84c0 100644
--- a/tests/DeferredDisplayListTest.cpp
+++ b/tests/DeferredDisplayListTest.cpp
@@ -121,13 +121,7 @@ public:
}
}
- // Create a DDL whose characterization captures the current settings
- std::unique_ptr<SkDeferredDisplayList> createDDL(GrContext* context) const {
- sk_sp<SkSurface> s = this->make(context);
- if (!s) {
- return nullptr;
- }
-
+ SkSurfaceCharacterization createCharacterization(GrContext* context) const {
int maxResourceCount;
size_t maxResourceBytes;
context->getResourceCacheLimits(&maxResourceCount, &maxResourceBytes);
@@ -141,6 +135,12 @@ public:
SkSurfaceCharacterization c = context->threadSafeProxy()->createCharacterization(
maxResourceBytes, ii, backendFormat, fSampleCount,
fOrigin, fSurfaceProps, fShouldCreateMipMaps);
+ return c;
+ }
+
+ // Create a DDL whose characterization captures the current settings
+ std::unique_ptr<SkDeferredDisplayList> createDDL(GrContext* context) const {
+ SkSurfaceCharacterization c = this->createCharacterization(context);
SkAssertResult(c.isValid());
SkDeferredDisplayListRecorder r(c);
@@ -205,6 +205,7 @@ private:
bool fShouldCreateMipMaps;
};
+////////////////////////////////////////////////////////////////////////////////
// This tests SkSurfaceCharacterization/SkSurface compatibility
DEF_GPUTEST_FOR_ALL_CONTEXTS(DDLSurfaceCharacterizationTest, reporter, ctxInfo) {
GrContext* context = ctxInfo.grContext();
@@ -258,6 +259,8 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(DDLSurfaceCharacterizationTest, reporter, ctxInfo)
}
if (SurfaceParameters::kMipMipCount == i && !context->caps()->mipMapSupport()) {
+ // If changing the mipmap setting won't result in a different surface characterization,
+ // skip this step
continue;
}
@@ -345,6 +348,35 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(DDLSurfaceCharacterizationTest, reporter, ctxInfo)
}
}
+////////////////////////////////////////////////////////////////////////////////
+// This tests the SkSurface::MakeRenderTarget variant that takes an SkSurfaceCharacterization.
+// In particular, the SkSurface and the SkSurfaceCharacterization should always be compatible.
+DEF_GPUTEST_FOR_ALL_CONTEXTS(DDLMakeRenderTargetTest, reporter, ctxInfo) {
+ GrContext* context = ctxInfo.grContext();
+
+ for (int i = 0; i < SurfaceParameters::kNumParams; ++i) {
+ SurfaceParameters params;
+ params.modify(i);
+
+ SkSurfaceCharacterization c = params.createCharacterization(context);
+
+ sk_sp<SkSurface> s = params.make(context);
+ if (!s) {
+ REPORTER_ASSERT(reporter, !c.isValid());
+ continue;
+ }
+
+ REPORTER_ASSERT(reporter, c.isValid());
+
+ s = SkSurface::MakeRenderTarget(context, c, SkBudgeted::kYes);
+ REPORTER_ASSERT(reporter, s);
+
+ SkSurface_Gpu* g = static_cast<SkSurface_Gpu*>(s.get());
+ REPORTER_ASSERT(reporter, g->isCompatible(c));
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
static constexpr int kSize = 8;
struct TextureReleaseChecker {
@@ -411,6 +443,7 @@ static void dummy_fulfill_proc(void*, GrBackendTexture*) { SkASSERT(0); }
static void dummy_release_proc(void*) { SkASSERT(0); }
static void dummy_done_proc(void*) { }
+////////////////////////////////////////////////////////////////////////////////
// Test out the behavior of an invalid DDLRecorder
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLInvalidRecorder, reporter, ctxInfo) {
GrContext* context = ctxInfo.grContext();
@@ -450,6 +483,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLInvalidRecorder, reporter, ctxInfo) {
}
+////////////////////////////////////////////////////////////////////////////////
// Ensure that flushing while DDL recording doesn't cause a crash
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLFlushWhileRecording, reporter, ctxInfo) {
GrContext* context = ctxInfo.grContext();
@@ -467,6 +501,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLFlushWhileRecording, reporter, ctxInfo) {
canvas->getGrContext()->flush();
}
+////////////////////////////////////////////////////////////////////////////////
// Check that the texture-specific flags (i.e., for external & rectangle textures) work
// for promise images. As such, this is a GL-only test.
DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(DDLTextureFlagsTest, reporter, ctxInfo) {