summaryrefslogtreecommitdiff
path: root/chromium/third_party/skia/tools/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/skia/tools/gpu')
-rw-r--r--chromium/third_party/skia/tools/gpu/GrContextFactory.cpp3
-rw-r--r--chromium/third_party/skia/tools/gpu/GrTest.cpp8
-rw-r--r--chromium/third_party/skia/tools/gpu/MemoryCache.cpp3
-rw-r--r--chromium/third_party/skia/tools/gpu/MemoryCache.h9
-rw-r--r--chromium/third_party/skia/tools/gpu/TestContext.cpp1
-rw-r--r--chromium/third_party/skia/tools/gpu/TestOps.cpp39
-rw-r--r--chromium/third_party/skia/tools/gpu/YUVUtils.cpp25
-rw-r--r--chromium/third_party/skia/tools/gpu/YUVUtils.h40
-rw-r--r--chromium/third_party/skia/tools/gpu/atlastext/GLTestAtlasTextRenderer.cpp483
-rw-r--r--chromium/third_party/skia/tools/gpu/atlastext/GLTestAtlasTextRenderer.h25
-rw-r--r--chromium/third_party/skia/tools/gpu/atlastext/TestAtlasTextRenderer.h37
-rw-r--r--chromium/third_party/skia/tools/gpu/d3d/D3DTestContext.cpp1
-rw-r--r--chromium/third_party/skia/tools/gpu/dawn/DawnTestContext.cpp12
-rw-r--r--chromium/third_party/skia/tools/gpu/dawn/DawnTestContext.h5
-rw-r--r--chromium/third_party/skia/tools/gpu/gl/GLTestContext.cpp35
-rw-r--r--chromium/third_party/skia/tools/gpu/gl/GLTestContext.h4
-rw-r--r--chromium/third_party/skia/tools/gpu/gl/angle/GLTestContext_angle.cpp23
-rw-r--r--chromium/third_party/skia/tools/gpu/gl/egl/CreatePlatformGLTestContext_egl.cpp6
-rw-r--r--chromium/third_party/skia/tools/gpu/gl/interface/templates.go48
-rw-r--r--chromium/third_party/skia/tools/gpu/vk/VkTestHelper.cpp109
-rw-r--r--chromium/third_party/skia/tools/gpu/vk/VkTestHelper.h71
-rw-r--r--chromium/third_party/skia/tools/gpu/vk/VkTestUtils.cpp5
-rw-r--r--chromium/third_party/skia/tools/gpu/vk/VkYcbcrSamplerHelper.cpp196
-rw-r--r--chromium/third_party/skia/tools/gpu/vk/VkYcbcrSamplerHelper.h48
24 files changed, 612 insertions, 624 deletions
diff --git a/chromium/third_party/skia/tools/gpu/GrContextFactory.cpp b/chromium/third_party/skia/tools/gpu/GrContextFactory.cpp
index 13cc9792050..f7356f57fb8 100644
--- a/chromium/third_party/skia/tools/gpu/GrContextFactory.cpp
+++ b/chromium/third_party/skia/tools/gpu/GrContextFactory.cpp
@@ -90,7 +90,8 @@ void GrContextFactory::abandonContexts() {
auto restore = context.fTestContext->makeCurrentAndAutoRestore();
context.fTestContext->testAbandon();
}
- bool requiresEarlyAbandon = (context.fGrContext->backend() == GrBackendApi::kVulkan);
+ GrBackendApi api = context.fGrContext->backend();
+ bool requiresEarlyAbandon = api == GrBackendApi::kVulkan || api == GrBackendApi::kDawn;
if (requiresEarlyAbandon) {
context.fGrContext->abandonContext();
}
diff --git a/chromium/third_party/skia/tools/gpu/GrTest.cpp b/chromium/third_party/skia/tools/gpu/GrTest.cpp
index 2a030d43eb0..d6286674e72 100644
--- a/chromium/third_party/skia/tools/gpu/GrTest.cpp
+++ b/chromium/third_party/skia/tools/gpu/GrTest.cpp
@@ -54,20 +54,18 @@ int GrResourceCache::countUniqueKeysWithTag(const char* tag) const {
///////////////////////////////////////////////////////////////////////////////
-#define ASSERT_SINGLE_OWNER \
- SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fRenderTargetContext->singleOwner());)
-
+#define ASSERT_SINGLE_OWNER GR_ASSERT_SINGLE_OWNER(fRenderTargetContext->singleOwner())
uint32_t GrRenderTargetContextPriv::testingOnly_getOpsTaskID() {
return fRenderTargetContext->getOpsTask()->uniqueID();
}
void GrRenderTargetContextPriv::testingOnly_addDrawOp(std::unique_ptr<GrDrawOp> op) {
- this->testingOnly_addDrawOp(GrNoClip(), std::move(op));
+ this->testingOnly_addDrawOp(nullptr, std::move(op), {});
}
void GrRenderTargetContextPriv::testingOnly_addDrawOp(
- const GrClip& clip,
+ const GrClip* clip,
std::unique_ptr<GrDrawOp> op,
const std::function<GrRenderTargetContext::WillAddOpFn>& willAddFn) {
ASSERT_SINGLE_OWNER
diff --git a/chromium/third_party/skia/tools/gpu/MemoryCache.cpp b/chromium/third_party/skia/tools/gpu/MemoryCache.cpp
index d8fdaf71578..93ef2b14a47 100644
--- a/chromium/third_party/skia/tools/gpu/MemoryCache.cpp
+++ b/chromium/third_party/skia/tools/gpu/MemoryCache.cpp
@@ -57,6 +57,7 @@ void MemoryCache::store(const SkData& key, const SkData& data) {
SkDebugf("Store Key: %s\n\tData: %s\n\n", data_to_str(key).c_str(),
data_to_str(data).c_str());
}
+ ++fCacheStoreCnt;
fMap[Key(key)] = Value(data);
}
@@ -96,7 +97,7 @@ void MemoryCache::writeShadersToDisk(const char* path, GrBackendApi api) {
// Even with the SPIR-V switches, it seems like we must use .spv, or malisc tries to
// run glslang on the input.
const char* ext = GrBackendApi::kOpenGL == api ? "frag" : "spv";
- SkReader32 reader(data->data(), data->size());
+ SkReadBuffer reader(data->data(), data->size());
GrPersistentCacheUtils::GetType(&reader); // Shader type tag
GrPersistentCacheUtils::UnpackCachedShaders(&reader, shaders,
inputsIgnored, kGrShaderTypeCount);
diff --git a/chromium/third_party/skia/tools/gpu/MemoryCache.h b/chromium/third_party/skia/tools/gpu/MemoryCache.h
index 22911a5413b..f70cf1388e8 100644
--- a/chromium/third_party/skia/tools/gpu/MemoryCache.h
+++ b/chromium/third_party/skia/tools/gpu/MemoryCache.h
@@ -28,14 +28,18 @@ public:
MemoryCache(const MemoryCache&) = delete;
MemoryCache& operator=(const MemoryCache&) = delete;
void reset() {
- fCacheMissCnt = 0;
+ this->resetCacheStats();
fMap.clear();
}
sk_sp<SkData> load(const SkData& key) override;
void store(const SkData& key, const SkData& data) override;
int numCacheMisses() const { return fCacheMissCnt; }
- void resetNumCacheMisses() { fCacheMissCnt = 0; }
+ int numCacheStores() const { return fCacheStoreCnt; }
+ void resetCacheStats() {
+ fCacheMissCnt = 0;
+ fCacheStoreCnt = 0;
+ }
void writeShadersToDisk(const char* path, GrBackendApi backend);
@@ -80,6 +84,7 @@ private:
};
int fCacheMissCnt = 0;
+ int fCacheStoreCnt = 0;
std::unordered_map<Key, Value, Hash> fMap;
};
diff --git a/chromium/third_party/skia/tools/gpu/TestContext.cpp b/chromium/third_party/skia/tools/gpu/TestContext.cpp
index cdd86c4fc4b..9b9e5dcbb9d 100644
--- a/chromium/third_party/skia/tools/gpu/TestContext.cpp
+++ b/chromium/third_party/skia/tools/gpu/TestContext.cpp
@@ -54,6 +54,7 @@ void TestContext::flushAndWaitOnSync(GrContext* context) {
flushInfo.fFinishedContext = fFinishTrackers[fCurrentFlushIdx].get();
context->flush(flushInfo);
+ context->submit();
fCurrentFlushIdx = (fCurrentFlushIdx + 1) % SK_ARRAY_COUNT(fFinishTrackers);
}
diff --git a/chromium/third_party/skia/tools/gpu/TestOps.cpp b/chromium/third_party/skia/tools/gpu/TestOps.cpp
index ff5201a2c98..1ef7420d74c 100644
--- a/chromium/third_party/skia/tools/gpu/TestOps.cpp
+++ b/chromium/third_party/skia/tools/gpu/TestOps.cpp
@@ -32,26 +32,29 @@ public:
const char* name() const override { return "TestRectOp::GP"; }
- GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps& caps) const override;
+ GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps& caps) const override {
+ return new GLSLGP();
+ }
- void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
+ void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const override {
+ GLSLGP::GenKey(*this, b);
+ }
bool wideColor() const { return fInColor.cpuType() != kUByte4_norm_GrVertexAttribType; }
private:
- Attribute fInPosition = {"inPosition", kFloat2_GrVertexAttribType, kFloat2_GrSLType};
- Attribute fInLocalCoords = {"inLocalCoords", kFloat2_GrVertexAttribType, kFloat2_GrSLType};
- Attribute fInColor;
- SkMatrix fLocalMatrix;
-};
-
-GrGLSLPrimitiveProcessor* GP::createGLSLInstance(const GrShaderCaps& caps) const {
class GLSLGP : public GrGLSLGeometryProcessor {
+ public:
void setData(const GrGLSLProgramDataManager& pdman,
const GrPrimitiveProcessor& pp,
const CoordTransformRange& transformRange) override {
const auto& gp = pp.cast<GP>();
- this->setTransformDataHelper(gp.fLocalMatrix, pdman, transformRange);
+ this->setTransformDataHelper(pdman, transformRange);
+ this->setTransform(pdman, fLocalMatrixUni, gp.fLocalMatrix);
+ }
+
+ static void GenKey(const GP& gp, GrProcessorKeyBuilder* b) {
+ b->add32(ComputeMatrixKey(gp.fLocalMatrix));
}
private:
@@ -65,13 +68,19 @@ GrGLSLPrimitiveProcessor* GP::createGLSLInstance(const GrShaderCaps& caps) const
args.fFragBuilder->codeAppendf("%s = %s;", args.fOutputColor, colorVarying.fsIn());
args.fFragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage);
this->writeOutputPosition(args.fVertBuilder, gpArgs, gp.fInPosition.name());
- this->emitTransforms(args.fVertBuilder, args.fVaryingHandler, args.fUniformHandler,
- gp.fInLocalCoords.asShaderVar(), gp.fLocalMatrix,
- args.fFPCoordTransformHandler);
+ this->writeLocalCoord(args.fVertBuilder, args.fUniformHandler, gpArgs,
+ gp.fInLocalCoords.asShaderVar(), gp.fLocalMatrix,
+ &fLocalMatrixUni);
}
+
+ UniformHandle fLocalMatrixUni;
};
- return new GLSLGP();
-}
+
+ Attribute fInPosition = {"inPosition", kFloat2_GrVertexAttribType, kFloat2_GrSLType};
+ Attribute fInLocalCoords = {"inLocalCoords", kFloat2_GrVertexAttribType, kFloat2_GrSLType};
+ Attribute fInColor;
+ SkMatrix fLocalMatrix;
+};
class TestRectOp final : public GrMeshDrawOp {
public:
diff --git a/chromium/third_party/skia/tools/gpu/YUVUtils.cpp b/chromium/third_party/skia/tools/gpu/YUVUtils.cpp
index eb4ca2c3d12..5b941358e3f 100644
--- a/chromium/third_party/skia/tools/gpu/YUVUtils.cpp
+++ b/chromium/third_party/skia/tools/gpu/YUVUtils.cpp
@@ -85,4 +85,29 @@ bool LazyYUVImage::ensureYUVImage(GrContext* context) {
return fYUVImage != nullptr;
}
+///////////////////////////////////////////////////////////////////////////////////////////////////
+void YUVABackendReleaseContext::Unwind(GrContext* context, YUVABackendReleaseContext* beContext) {
+ // Some backends (e.g., Vulkan) require that all work associated w/ texture
+ // creation be completed before deleting the textures.
+ GrFlushInfo flushInfoSyncCpu;
+ flushInfoSyncCpu.fFlags = kSyncCpu_GrFlushFlag;
+ context->flush(flushInfoSyncCpu);
+ context->submit(true);
+
+ delete beContext;
+}
+
+YUVABackendReleaseContext::YUVABackendReleaseContext(GrContext* context) : fContext(context) {
+ SkASSERT(context->priv().getGpu());
+ SkASSERT(context->priv().asDirectContext());
+}
+
+YUVABackendReleaseContext::~YUVABackendReleaseContext() {
+ for (int i = 0; i < 4; ++i) {
+ if (fBETextures[i].isValid()) {
+ fContext->deleteBackendTexture(fBETextures[i]);
+ }
+ }
+}
+
} // namespace sk_gpu_test
diff --git a/chromium/third_party/skia/tools/gpu/YUVUtils.h b/chromium/third_party/skia/tools/gpu/YUVUtils.h
index f6097b9476d..bfca6f41fe3 100644
--- a/chromium/third_party/skia/tools/gpu/YUVUtils.h
+++ b/chromium/third_party/skia/tools/gpu/YUVUtils.h
@@ -11,6 +11,7 @@
#include "include/core/SkImage.h"
#include "include/core/SkYUVAIndex.h"
#include "include/core/SkYUVASizeInfo.h"
+#include "include/gpu/GrBackendSurface.h"
#include "src/core/SkAutoMalloc.h"
class SkData;
@@ -49,6 +50,45 @@ private:
bool ensureYUVImage(GrContext* context);
};
+// A helper for managing the lifetime of backend textures for YUVA images.
+class YUVABackendReleaseContext {
+public:
+ // A stock 'TextureReleaseProc' to use with this class
+ static void Release(void* releaseContext) {
+ auto beContext = reinterpret_cast<YUVABackendReleaseContext*>(releaseContext);
+
+ delete beContext;
+ }
+
+ // Given how and when backend textures are created, just deleting this object often
+ // isn't enough. This helper encapsulates the extra work needed.
+ static void Unwind(GrContext* context, YUVABackendReleaseContext* beContext);
+
+ YUVABackendReleaseContext(GrContext* context);
+ ~YUVABackendReleaseContext();
+
+ void set(int index, const GrBackendTexture& beTex) {
+ SkASSERT(index >= 0 && index < 4);
+ SkASSERT(!fBETextures[index].isValid());
+ SkASSERT(beTex.isValid());
+
+ fBETextures[index] = beTex;
+ }
+
+ const GrBackendTexture* beTextures() const { return fBETextures; }
+
+ const GrBackendTexture& beTexture(int index) {
+ SkASSERT(index >= 0 && index < 4);
+ SkASSERT(fBETextures[index].isValid());
+ return fBETextures[index];
+ }
+
+private:
+ GrContext* fContext;
+ GrBackendTexture fBETextures[4];
+};
+
+
} // namespace sk_gpu_test
#endif // YUVUtils_DEFINED
diff --git a/chromium/third_party/skia/tools/gpu/atlastext/GLTestAtlasTextRenderer.cpp b/chromium/third_party/skia/tools/gpu/atlastext/GLTestAtlasTextRenderer.cpp
deleted file mode 100644
index c8dc0540fce..00000000000
--- a/chromium/third_party/skia/tools/gpu/atlastext/GLTestAtlasTextRenderer.cpp
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "include/core/SkBitmap.h"
-#include "src/gpu/gl/GrGLDefines.h"
-#include "src/gpu/gl/GrGLUtil.h"
-#include "tools/gpu/atlastext/GLTestAtlasTextRenderer.h"
-#include "tools/gpu/atlastext/TestAtlasTextRenderer.h"
-#include "tools/gpu/gl/GLTestContext.h"
-
-using sk_gpu_test::GLTestContext;
-
-namespace {
-
-class GLTestAtlasTextRenderer : public sk_gpu_test::TestAtlasTextRenderer {
-public:
- GLTestAtlasTextRenderer(std::unique_ptr<GLTestContext>);
-
- void* createTexture(AtlasFormat, int width, int height) override;
-
- void deleteTexture(void* textureHandle) override;
-
- void setTextureData(void* textureHandle, const void* data, int x, int y, int width, int height,
- size_t rowBytes) override;
-
- void drawSDFGlyphs(void* targetHandle, void* textureHandle, const SDFVertex vertices[],
- int quadCnt) override;
-
- void* makeTargetHandle(int width, int height) override;
-
- void targetDeleted(void* targetHandle) override;
-
- SkBitmap readTargetHandle(void* targetHandle) override;
-
- void clearTarget(void* targetHandle, uint32_t color) override;
-
- bool initialized() const { return 0 != fProgram; }
-
-private:
- struct AtlasTexture {
- GrGLuint fID;
- AtlasFormat fFormat;
- int fWidth;
- int fHeight;
- };
-
- struct Target {
- GrGLuint fFBOID;
- GrGLuint fRBID;
- int fWidth;
- int fHeight;
- };
-
- std::unique_ptr<GLTestContext> fContext;
- GrGLuint fProgram = 0;
- GrGLint fDstScaleAndTranslateLocation = 0;
- GrGLint fAtlasInvSizeLocation = 0;
- GrGLint fSamplerLocation = 0;
-};
-
-#define callgl(NAME, ...) fContext->gl()->fFunctions.f##NAME(__VA_ARGS__)
-#define checkgl() \
- do { \
- static constexpr auto line = __LINE__; \
- auto error = fContext->gl()->fFunctions.fGetError(); \
- if (error != GR_GL_NO_ERROR) { \
- SkDebugf("GL ERROR: 0x%x, line %d\n", error, line); \
- } \
- } while (false)
-
-GLTestAtlasTextRenderer::GLTestAtlasTextRenderer(std::unique_ptr<GLTestContext> context)
- : fContext(std::move(context)) {
- auto restore = fContext->makeCurrentAndAutoRestore();
-
- // First check whether the GL is supported so we can avoid spammy failures on systems
- // where the GL simply doesn't work with this class.
- const char* versionStr = reinterpret_cast<const char*>(callgl(GetString, GR_GL_VERSION));
- auto version = GrGLGetVersionFromString(versionStr);
- auto standard = GrGLGetStandardInUseFromString(versionStr);
- switch (standard) {
- case kWebGL_GrGLStandard:
- case kNone_GrGLStandard:
- return;
- case kGLES_GrGLStandard:
- if (version < GR_GL_VER(3, 0)) {
- return;
- }
- break;
- case kGL_GrGLStandard: {
- if (version < GR_GL_VER(4, 3)) {
- return;
- }
- GrGLint profileMask;
- callgl(GetIntegerv, GR_GL_CONTEXT_PROFILE_MASK, &profileMask);
- if (profileMask & GR_GL_CONTEXT_CORE_PROFILE_BIT) {
- return;
- }
- }
- }
-
- auto vs = callgl(CreateShader, GR_GL_VERTEX_SHADER);
- static constexpr char kGLVersionString[] = "#version 430 compatibility";
- static constexpr char kGLESVersionString[] = "#version 300 es";
- GrGLint lengths[2];
- const GrGLchar* strings[2];
- switch (fContext->gl()->fStandard) {
- case kGL_GrGLStandard:
- strings[0] = kGLVersionString;
- lengths[0] = static_cast<GrGLint>(SK_ARRAY_COUNT(kGLVersionString)) - 1;
- break;
- case kGLES_GrGLStandard:
- strings[0] = kGLESVersionString;
- lengths[0] = static_cast<GrGLint>(SK_ARRAY_COUNT(kGLESVersionString)) - 1;
- break;
- default:
- strings[0] = nullptr;
- lengths[0] = 0;
- break;
- }
-
- static constexpr const char kVS[] = R"(
- uniform vec4 uDstScaleAndTranslate;
- uniform vec2 uAtlasInvSize;
-
- layout (location = 0) in vec3 inPosition;
- layout (location = 1) in vec4 inColor;
- layout (location = 2) in uvec2 inTextureCoords;
-
- out vec2 vTexCoord;
- out vec4 vColor;
- out vec2 vIntTexCoord;
-
- void main() {
- vec2 intCoords;
- // floor(vec2) doesn't seem to work on some ES devices.
- intCoords.x = floor(float(inTextureCoords.x));
- intCoords.y = floor(float(inTextureCoords.y));
- vTexCoord = intCoords * uAtlasInvSize;
- vIntTexCoord = intCoords;
- vColor = inColor;
- gl_Position = vec4(inPosition.x * uDstScaleAndTranslate.x + uDstScaleAndTranslate.y,
- inPosition.y * uDstScaleAndTranslate.z + uDstScaleAndTranslate.w,
- 0.0, inPosition.z);
- }
- )";
- strings[1] = kVS;
- lengths[1] = SK_ARRAY_COUNT(kVS) - 1;
- callgl(ShaderSource, vs, 2, strings, lengths);
- callgl(CompileShader, vs);
- GrGLint compileStatus;
- callgl(GetShaderiv, vs, GR_GL_COMPILE_STATUS, &compileStatus);
- if (compileStatus == GR_GL_FALSE) {
- GrGLint logLength;
- callgl(GetShaderiv, vs, GR_GL_INFO_LOG_LENGTH, &logLength);
- std::unique_ptr<GrGLchar[]> log(new GrGLchar[logLength + 1]);
- log[logLength] = '\0';
- callgl(GetShaderInfoLog, vs, logLength, &logLength, log.get());
- SkDebugf("Vertex Shader failed to compile\n%s", log.get());
- callgl(DeleteShader, vs);
- return;
- }
-
- auto fs = callgl(CreateShader, GR_GL_FRAGMENT_SHADER);
- static constexpr const char kFS[] = R"(
- uniform sampler2D uSampler;
-
- in vec2 vTexCoord;
- in vec4 vColor;
- in vec2 vIntTexCoord;
-
- layout (location = 0) out vec4 outColor;
-
- void main() {
- float sdfValue = texture(uSampler, vTexCoord).r;
- float distance = 7.96875 * (sdfValue - 0.50196078431000002);
- vec2 dist_grad = vec2(dFdx(distance), dFdy(distance));
- vec2 Jdx = dFdx(vIntTexCoord);
- vec2 Jdy = dFdy(vIntTexCoord);
- float dg_len2 = dot(dist_grad, dist_grad);
- if (dg_len2 < 0.0001) {
- dist_grad = vec2(0.7071, 0.7071);
- } else {
- dist_grad = dist_grad * inversesqrt(dg_len2);
- }
- vec2 grad = vec2(dist_grad.x * Jdx.x + dist_grad.y * Jdy.x,
- dist_grad.x * Jdx.y + dist_grad.y * Jdy.y);
- float afwidth = abs(0.65000000000000002 * length(grad));
- float value = smoothstep(-afwidth, afwidth, distance);
- outColor = value * vec4(vColor.rgb * vColor.a, vColor.a);
- }
- )";
- strings[1] = kFS;
- lengths[1] = SK_ARRAY_COUNT(kFS) - 1;
- callgl(ShaderSource, fs, 2, strings, lengths);
- callgl(CompileShader, fs);
- callgl(GetShaderiv, fs, GR_GL_COMPILE_STATUS, &compileStatus);
- if (compileStatus == GR_GL_FALSE) {
- GrGLint logLength;
- callgl(GetShaderiv, fs, GR_GL_INFO_LOG_LENGTH, &logLength);
- std::unique_ptr<GrGLchar[]> log(new GrGLchar[logLength + 1]);
- log[logLength] = '\0';
- callgl(GetShaderInfoLog, fs, logLength, &logLength, log.get());
- SkDebugf("Fragment Shader failed to compile\n%s", log.get());
- callgl(DeleteShader, vs);
- callgl(DeleteShader, fs);
- return;
- }
-
- fProgram = callgl(CreateProgram);
- if (!fProgram) {
- callgl(DeleteShader, vs);
- callgl(DeleteShader, fs);
- return;
- }
-
- callgl(AttachShader, fProgram, vs);
- callgl(AttachShader, fProgram, fs);
- callgl(LinkProgram, fProgram);
- GrGLint linkStatus;
- callgl(GetProgramiv, fProgram, GR_GL_LINK_STATUS, &linkStatus);
- if (linkStatus == GR_GL_FALSE) {
- GrGLint logLength = 0;
- callgl(GetProgramiv, vs, GR_GL_INFO_LOG_LENGTH, &logLength);
- std::unique_ptr<GrGLchar[]> log(new GrGLchar[logLength + 1]);
- log[logLength] = '\0';
- callgl(GetProgramInfoLog, vs, logLength, &logLength, log.get());
- SkDebugf("Program failed to link\n%s", log.get());
- callgl(DeleteShader, vs);
- callgl(DeleteShader, fs);
- callgl(DeleteProgram, fProgram);
- fProgram = 0;
- return;
- }
- fDstScaleAndTranslateLocation = callgl(GetUniformLocation, fProgram, "uDstScaleAndTranslate");
- fAtlasInvSizeLocation = callgl(GetUniformLocation, fProgram, "uAtlasInvSize");
- fSamplerLocation = callgl(GetUniformLocation, fProgram, "uSampler");
- if (fDstScaleAndTranslateLocation < 0 || fAtlasInvSizeLocation < 0 || fSamplerLocation < 0) {
- callgl(DeleteShader, vs);
- callgl(DeleteShader, fs);
- callgl(DeleteProgram, fProgram);
- fProgram = 0;
- }
-
- checkgl();
-}
-
-inline bool atlas_format_to_gl_types(SkAtlasTextRenderer::AtlasFormat format,
- GrGLenum* internalFormat, GrGLenum* externalFormat,
- GrGLenum* type) {
- switch (format) {
- case SkAtlasTextRenderer::AtlasFormat::kA8:
- *internalFormat = GR_GL_R8;
- *externalFormat = GR_GL_RED;
- *type = GR_GL_UNSIGNED_BYTE;
- return true;
- }
- return false;
-}
-
-inline int atlas_format_bytes_per_pixel(SkAtlasTextRenderer::AtlasFormat format) {
- switch (format) {
- case SkAtlasTextRenderer::AtlasFormat::kA8:
- return 1;
- }
- return 0;
-}
-
-void* GLTestAtlasTextRenderer::createTexture(AtlasFormat format, int width, int height) {
- GrGLenum internalFormat;
- GrGLenum externalFormat;
- GrGLenum type;
- if (!atlas_format_to_gl_types(format, &internalFormat, &externalFormat, &type)) {
- return nullptr;
- }
- auto restore = fContext->makeCurrentAndAutoRestore();
-
- GrGLuint id;
- callgl(GenTextures, 1, &id);
- if (!id) {
- return nullptr;
- }
-
- callgl(BindTexture, GR_GL_TEXTURE_2D, id);
- callgl(TexImage2D, GR_GL_TEXTURE_2D, 0, internalFormat, width, height, 0, externalFormat, type,
- nullptr);
- checkgl();
-
- AtlasTexture* atlas = new AtlasTexture;
- atlas->fID = id;
- atlas->fFormat = format;
- atlas->fWidth = width;
- atlas->fHeight = height;
- return atlas;
-}
-
-void GLTestAtlasTextRenderer::deleteTexture(void* textureHandle) {
- auto restore = fContext->makeCurrentAndAutoRestore();
-
- auto* atlasTexture = reinterpret_cast<const AtlasTexture*>(textureHandle);
-
- callgl(DeleteTextures, 1, &atlasTexture->fID);
- checkgl();
-
- delete atlasTexture;
-}
-
-void GLTestAtlasTextRenderer::setTextureData(void* textureHandle, const void* data, int x, int y,
- int width, int height, size_t rowBytes) {
- auto restore = fContext->makeCurrentAndAutoRestore();
-
- auto atlasTexture = reinterpret_cast<const AtlasTexture*>(textureHandle);
-
- GrGLenum internalFormat;
- GrGLenum externalFormat;
- GrGLenum type;
- if (!atlas_format_to_gl_types(atlasTexture->fFormat, &internalFormat, &externalFormat, &type)) {
- return;
- }
- int bpp = atlas_format_bytes_per_pixel(atlasTexture->fFormat);
- GrGLint rowLength = static_cast<GrGLint>(rowBytes / bpp);
- if (static_cast<size_t>(rowLength * bpp) != rowBytes) {
- return;
- }
- callgl(PixelStorei, GR_GL_UNPACK_ALIGNMENT, 1);
- callgl(PixelStorei, GR_GL_UNPACK_ROW_LENGTH, rowLength);
- callgl(BindTexture, GR_GL_TEXTURE_2D, atlasTexture->fID);
- callgl(TexSubImage2D, GR_GL_TEXTURE_2D, 0, x, y, width, height, externalFormat, type, data);
- checkgl();
-}
-
-void GLTestAtlasTextRenderer::drawSDFGlyphs(void* targetHandle, void* textureHandle,
- const SDFVertex vertices[], int quadCnt) {
- auto restore = fContext->makeCurrentAndAutoRestore();
-
- auto target = reinterpret_cast<const Target*>(targetHandle);
- auto atlas = reinterpret_cast<const AtlasTexture*>(textureHandle);
-
- callgl(UseProgram, fProgram);
-
- callgl(ActiveTexture, GR_GL_TEXTURE0);
- callgl(BindTexture, GR_GL_TEXTURE_2D, atlas->fID);
- callgl(TexParameteri, GR_GL_TEXTURE_2D, GR_GL_TEXTURE_MAG_FILTER, GR_GL_LINEAR);
- callgl(TexParameteri, GR_GL_TEXTURE_2D, GR_GL_TEXTURE_MIN_FILTER, GR_GL_LINEAR);
-
- float uniformScaleAndTranslate[4] = {2.f / target->fWidth, -1.f, 2.f / target->fHeight, -1.f};
- callgl(Uniform4fv, fDstScaleAndTranslateLocation, 1, uniformScaleAndTranslate);
- callgl(Uniform2f, fAtlasInvSizeLocation, 1.f / atlas->fWidth, 1.f / atlas->fHeight);
- callgl(Uniform1i, fSamplerLocation, 0);
-
- callgl(BindFramebuffer, GR_GL_FRAMEBUFFER, target->fFBOID);
- callgl(Viewport, 0, 0, target->fWidth, target->fHeight);
-
- callgl(Enable, GR_GL_BLEND);
- callgl(BlendFunc, GR_GL_ONE, GR_GL_ONE_MINUS_SRC_ALPHA);
- callgl(Disable, GR_GL_DEPTH_TEST);
-
- callgl(BindVertexArray, 0);
- callgl(BindBuffer, GR_GL_ARRAY_BUFFER, 0);
- callgl(BindBuffer, GR_GL_ELEMENT_ARRAY_BUFFER, 0);
- callgl(VertexAttribPointer, 0, 3, GR_GL_FLOAT, GR_GL_FALSE, sizeof(SDFVertex), vertices);
- size_t colorOffset = 3 * sizeof(float);
- callgl(VertexAttribPointer, 1, 4, GR_GL_UNSIGNED_BYTE, GR_GL_TRUE, sizeof(SDFVertex),
- reinterpret_cast<const char*>(vertices) + colorOffset);
- size_t texOffset = colorOffset + sizeof(uint32_t);
- callgl(VertexAttribIPointer, 2, 2, GR_GL_UNSIGNED_SHORT, sizeof(SDFVertex),
- reinterpret_cast<const char*>(vertices) + texOffset);
- callgl(EnableVertexAttribArray, 0);
- callgl(EnableVertexAttribArray, 1);
- callgl(EnableVertexAttribArray, 2);
-
- std::unique_ptr<uint16_t[]> indices(new uint16_t[quadCnt * 6]);
- for (int q = 0; q < quadCnt; ++q) {
- indices[q * 6 + 0] = 0 + 4 * q;
- indices[q * 6 + 1] = 1 + 4 * q;
- indices[q * 6 + 2] = 2 + 4 * q;
- indices[q * 6 + 3] = 2 + 4 * q;
- indices[q * 6 + 4] = 1 + 4 * q;
- indices[q * 6 + 5] = 3 + 4 * q;
- }
- callgl(DrawElements, GR_GL_TRIANGLES, 6 * quadCnt, GR_GL_UNSIGNED_SHORT, indices.get());
- checkgl();
-}
-
-void* GLTestAtlasTextRenderer::makeTargetHandle(int width, int height) {
- auto restore = fContext->makeCurrentAndAutoRestore();
-
- GrGLuint fbo;
- callgl(GenFramebuffers, 1, &fbo);
- if (!fbo) {
- return nullptr;
- }
- GrGLuint rb;
- callgl(GenRenderbuffers, 1, &rb);
- if (!rb) {
- callgl(DeleteFramebuffers, 1, &fbo);
- return nullptr;
- }
- callgl(BindFramebuffer, GR_GL_FRAMEBUFFER, fbo);
- callgl(BindRenderbuffer, GR_GL_RENDERBUFFER, rb);
- callgl(RenderbufferStorage, GR_GL_RENDERBUFFER, GR_GL_RGBA8, width, height);
- callgl(FramebufferRenderbuffer, GR_GL_FRAMEBUFFER, GR_GL_COLOR_ATTACHMENT0, GR_GL_RENDERBUFFER,
- rb);
- GrGLenum status = callgl(CheckFramebufferStatus, GR_GL_FRAMEBUFFER);
- if (GR_GL_FRAMEBUFFER_COMPLETE != status) {
- callgl(DeleteFramebuffers, 1, &fbo);
- callgl(DeleteRenderbuffers, 1, &rb);
- return nullptr;
- }
- callgl(Disable, GR_GL_SCISSOR_TEST);
- callgl(ClearColor, 0, 0, 0, 0.0);
- callgl(Clear, GR_GL_COLOR_BUFFER_BIT);
- checkgl();
- Target* target = new Target;
- target->fFBOID = fbo;
- target->fRBID = rb;
- target->fWidth = width;
- target->fHeight = height;
- return target;
-}
-
-void GLTestAtlasTextRenderer::targetDeleted(void* targetHandle) {
- auto restore = fContext->makeCurrentAndAutoRestore();
-
- Target* target = reinterpret_cast<Target*>(targetHandle);
- callgl(DeleteFramebuffers, 1, &target->fFBOID);
- callgl(DeleteRenderbuffers, 1, &target->fRBID);
- delete target;
-}
-
-SkBitmap GLTestAtlasTextRenderer::readTargetHandle(void* targetHandle) {
- auto restore = fContext->makeCurrentAndAutoRestore();
-
- Target* target = reinterpret_cast<Target*>(targetHandle);
-
- auto info =
- SkImageInfo::Make(target->fWidth, target->fHeight, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
- SkBitmap bmp;
- bmp.setInfo(info, sizeof(uint32_t) * target->fWidth);
- bmp.allocPixels();
-
- callgl(BindFramebuffer, GR_GL_FRAMEBUFFER, target->fFBOID);
- callgl(ReadPixels, 0, 0, target->fWidth, target->fHeight, GR_GL_RGBA, GR_GL_UNSIGNED_BYTE,
- bmp.getPixels());
- checkgl();
- return bmp;
-}
-
-void GLTestAtlasTextRenderer::clearTarget(void* targetHandle, uint32_t color) {
- auto restore = fContext->makeCurrentAndAutoRestore();
-
- Target* target = reinterpret_cast<Target*>(targetHandle);
- callgl(BindFramebuffer, GR_GL_FRAMEBUFFER, target->fFBOID);
- callgl(Disable, GR_GL_SCISSOR_TEST);
- float r = ((color >> 0) & 0xff) / 255.f;
- float g = ((color >> 8) & 0xff) / 255.f;
- float b = ((color >> 16) & 0xff) / 255.f;
- float a = ((color >> 24) & 0xff) / 255.f;
- callgl(ClearColor, r, g, b, a);
- callgl(Clear, GR_GL_COLOR_BUFFER_BIT);
-}
-
-} // anonymous namespace
-
-namespace sk_gpu_test {
-
-sk_sp<TestAtlasTextRenderer> MakeGLTestAtlasTextRenderer() {
- std::unique_ptr<GLTestContext> context(CreatePlatformGLTestContext(kGL_GrGLStandard));
- if (!context) {
- context.reset(CreatePlatformGLTestContext(kGLES_GrGLStandard));
- }
- if (!context) {
- return nullptr;
- }
- auto restorer = context->makeCurrentAndAutoRestore();
- auto renderer = sk_make_sp<GLTestAtlasTextRenderer>(std::move(context));
- return renderer->initialized() ? std::move(renderer) : nullptr;
-}
-
-} // namespace sk_gpu_test
diff --git a/chromium/third_party/skia/tools/gpu/atlastext/GLTestAtlasTextRenderer.h b/chromium/third_party/skia/tools/gpu/atlastext/GLTestAtlasTextRenderer.h
deleted file mode 100644
index d1536d303c6..00000000000
--- a/chromium/third_party/skia/tools/gpu/atlastext/GLTestAtlasTextRenderer.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GLTestAtlasTextRenderer_DEFINED
-#define GLTestAtlasTextRenderer_DEFINED
-
-#include "include/core/SkRefCnt.h"
-
-namespace sk_gpu_test {
-
-class TestAtlasTextRenderer;
-
-/**
- * Creates a TestAtlasTextRenderer that uses its own OpenGL context to implement
- * SkAtlasTextRenderer.
- */
-sk_sp<TestAtlasTextRenderer> MakeGLTestAtlasTextRenderer();
-
-} // namespace sk_gpu_test
-
-#endif
diff --git a/chromium/third_party/skia/tools/gpu/atlastext/TestAtlasTextRenderer.h b/chromium/third_party/skia/tools/gpu/atlastext/TestAtlasTextRenderer.h
deleted file mode 100644
index e928e76402b..00000000000
--- a/chromium/third_party/skia/tools/gpu/atlastext/TestAtlasTextRenderer.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef TestAtlasTextRenderer_DEFINED
-#define TestAtlasTextRenderer_DEFINED
-
-#include "include/atlastext/SkAtlasTextRenderer.h"
-#include "include/core/SkBitmap.h"
-
-namespace sk_gpu_test {
-
-class TestContext;
-
-/**
- * Base class for implementations of SkAtlasTextRenderer in order to test the SkAtlasText APIs.
- * Adds a helper for creating SkAtlasTextTargets and to read back the contents of a target as a
- * bitmap.
- */
-class TestAtlasTextRenderer : public SkAtlasTextRenderer {
-public:
- /** Returns a handle that can be used to construct a SkAtlasTextTarget instance. */
- virtual void* makeTargetHandle(int width, int height) = 0;
-
- /** Makes a SkBitmap of the target handle's contents. */
- virtual SkBitmap readTargetHandle(void* targetHandle) = 0;
-
- /** Clears the target to the specified color, encoded as RGBA (low to high byte order) */
- virtual void clearTarget(void* targetHandle, uint32_t color) = 0;
-};
-
-} // namespace sk_gpu_test
-
-#endif
diff --git a/chromium/third_party/skia/tools/gpu/d3d/D3DTestContext.cpp b/chromium/third_party/skia/tools/gpu/d3d/D3DTestContext.cpp
index ba00a36cd5c..fff7ca127ff 100644
--- a/chromium/third_party/skia/tools/gpu/d3d/D3DTestContext.cpp
+++ b/chromium/third_party/skia/tools/gpu/d3d/D3DTestContext.cpp
@@ -55,6 +55,7 @@ protected:
private:
D3DTestContextImpl(const GrD3DBackendContext& backendContext, bool ownsContext)
: D3DTestContext(backendContext, ownsContext) {
+ fFenceSupport = true;
}
void onPlatformMakeNotCurrent() const override {}
diff --git a/chromium/third_party/skia/tools/gpu/dawn/DawnTestContext.cpp b/chromium/third_party/skia/tools/gpu/dawn/DawnTestContext.cpp
index c23669709f7..58d755ea5c1 100644
--- a/chromium/third_party/skia/tools/gpu/dawn/DawnTestContext.cpp
+++ b/chromium/third_party/skia/tools/gpu/dawn/DawnTestContext.cpp
@@ -6,7 +6,6 @@
*/
#include "dawn/webgpu_cpp.h"
-#include "dawn_native/DawnNative.h"
#include "tools/gpu/dawn/DawnTestContext.h"
#ifdef SK_BUILD_FOR_UNIX
@@ -78,6 +77,10 @@ private:
ProcGetter* ProcGetter::fInstance;
#endif
+static void PrintDeviceError(WGPUErrorType, const char* message, void*) {
+ SkDebugf("Device error: %s\n", message);
+}
+
class DawnTestContextImpl : public sk_gpu_test::DawnTestContext {
public:
static wgpu::Device createDevice(const dawn_native::Instance& instance,
@@ -88,7 +91,7 @@ public:
std::vector<dawn_native::Adapter> adapters = instance.GetAdapters();
for (dawn_native::Adapter adapter : adapters) {
if (adapter.GetBackendType() == type) {
- return adapter.CreateDevice();
+ return wgpu::Device::Acquire(adapter.CreateDevice());
}
}
return nullptr;
@@ -125,6 +128,7 @@ public:
#endif
#endif
device = createDevice(*instance, type);
+ device.SetUncapturedErrorCallback(PrintDeviceError, 0);
}
if (!device) {
return nullptr;
@@ -150,15 +154,13 @@ protected:
private:
DawnTestContextImpl(std::unique_ptr<dawn_native::Instance> instance,
const wgpu::Device& device)
- : DawnTestContext(device)
- , fInstance(std::move(instance)) {
+ : DawnTestContext(std::move(instance), device) {
fFenceSupport = true;
}
void onPlatformMakeNotCurrent() const override {}
void onPlatformMakeCurrent() const override {}
std::function<void()> onPlatformGetAutoContextRestore() const override { return nullptr; }
- std::unique_ptr<dawn_native::Instance> fInstance;
typedef sk_gpu_test::DawnTestContext INHERITED;
};
diff --git a/chromium/third_party/skia/tools/gpu/dawn/DawnTestContext.h b/chromium/third_party/skia/tools/gpu/dawn/DawnTestContext.h
index 63f35f6f261..73b4e5df260 100644
--- a/chromium/third_party/skia/tools/gpu/dawn/DawnTestContext.h
+++ b/chromium/third_party/skia/tools/gpu/dawn/DawnTestContext.h
@@ -9,6 +9,7 @@
#define DawnTestContext_DEFINED
#include "tools/gpu/TestContext.h"
+#include <dawn_native/DawnNative.h>
#ifdef SK_DAWN
@@ -22,8 +23,10 @@ public:
}
protected:
- DawnTestContext(const wgpu::Device& device) : fDevice(device) {}
+ DawnTestContext(std::unique_ptr<dawn_native::Instance> instance, const wgpu::Device& device)
+ : fInstance(std::move(instance)), fDevice(device) {}
+ std::unique_ptr<dawn_native::Instance> fInstance;
wgpu::Device fDevice;
private:
diff --git a/chromium/third_party/skia/tools/gpu/gl/GLTestContext.cpp b/chromium/third_party/skia/tools/gpu/gl/GLTestContext.cpp
index 75c1fee8fd5..f40657c9388 100644
--- a/chromium/third_party/skia/tools/gpu/gl/GLTestContext.cpp
+++ b/chromium/third_party/skia/tools/gpu/gl/GLTestContext.cpp
@@ -222,41 +222,6 @@ void GLTestContext::finish() {
#endif
}
-GrGLuint GLTestContext::createTextureRectangle(int width, int height, GrGLenum internalFormat,
- GrGLenum externalFormat, GrGLenum externalType,
- GrGLvoid* data) {
-#ifdef SK_GL
- // Should match GrGLCaps check for fRectangleTextureSupport.
- if (kGL_GrGLStandard != fGL->fStandard ||
- (GrGLGetVersion(fGL.get()) < GR_GL_VER(3, 1) &&
- !fGL->fExtensions.has("GL_ARB_texture_rectangle") &&
- !fGL->fExtensions.has("GL_ANGLE_texture_rectangle"))) {
- return 0;
- }
-
- if (GrGLGetGLSLVersion(fGL.get()) < GR_GLSL_VER(1, 40)) {
- return 0;
- }
-
- GrGLuint id;
- GR_GL_CALL(fGL.get(), GenTextures(1, &id));
- GR_GL_CALL(fGL.get(), BindTexture(GR_GL_TEXTURE_RECTANGLE, id));
- GR_GL_CALL(fGL.get(), TexParameteri(GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_MAG_FILTER,
- GR_GL_NEAREST));
- GR_GL_CALL(fGL.get(), TexParameteri(GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_MIN_FILTER,
- GR_GL_NEAREST));
- GR_GL_CALL(fGL.get(), TexParameteri(GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_WRAP_S,
- GR_GL_CLAMP_TO_EDGE));
- GR_GL_CALL(fGL.get(), TexParameteri(GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_WRAP_T,
- GR_GL_CLAMP_TO_EDGE));
- GR_GL_CALL(fGL.get(), TexImage2D(GR_GL_TEXTURE_RECTANGLE, 0, internalFormat, width, height, 0,
- externalFormat, externalType, data));
- return id;
-#else
- return 0;
-#endif
-}
-
sk_sp<GrContext> GLTestContext::makeGrContext(const GrContextOptions& options) {
#ifdef SK_GL
return GrContext::MakeGL(fGL, options);
diff --git a/chromium/third_party/skia/tools/gpu/gl/GLTestContext.h b/chromium/third_party/skia/tools/gpu/gl/GLTestContext.h
index 601c3b9f18c..54b47492504 100644
--- a/chromium/third_party/skia/tools/gpu/gl/GLTestContext.h
+++ b/chromium/third_party/skia/tools/gpu/gl/GLTestContext.h
@@ -33,10 +33,6 @@ public:
virtual void destroyEGLImage(GrEGLImage) const { }
- /** Used for testing GL_TEXTURE_RECTANGLE integration. */
- GrGLuint createTextureRectangle(int width, int height, GrGLenum internalFormat,
- GrGLenum externalFormat, GrGLenum externalType, GrGLvoid* data);
-
/**
* Used for testing EGLImage integration. Takes a EGLImage and wraps it in a
* GL_TEXTURE_EXTERNAL_OES.
diff --git a/chromium/third_party/skia/tools/gpu/gl/angle/GLTestContext_angle.cpp b/chromium/third_party/skia/tools/gpu/gl/angle/GLTestContext_angle.cpp
index 57d39e00fad..24eeb2f0441 100644
--- a/chromium/third_party/skia/tools/gpu/gl/angle/GLTestContext_angle.cpp
+++ b/chromium/third_party/skia/tools/gpu/gl/angle/GLTestContext_angle.cpp
@@ -25,6 +25,8 @@
#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208
#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x320D
+#define EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE 0x3483
+
using sk_gpu_test::ANGLEBackend;
using sk_gpu_test::ANGLEContextVersion;
@@ -281,12 +283,20 @@ ANGLEGLContext::ANGLEGLContext(ANGLEBackend type, ANGLEContextVersion version,
}
int versionNum = ANGLEContextVersion::kES2 == version ? 2 : 3;
- const EGLint contextAttribs[] = {
+ std::vector<EGLint> contextAttribs = {
EGL_CONTEXT_CLIENT_VERSION, versionNum,
- EGL_NONE
};
+
+ const char* extensions = eglQueryString(fDisplay, EGL_EXTENSIONS);
+ if (strstr(extensions, "EGL_ANGLE_create_context_backwards_compatible")) {
+ contextAttribs.push_back(EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE);
+ contextAttribs.push_back(EGL_FALSE);
+ }
+
+ contextAttribs.push_back(EGL_NONE);
+
EGLContext eglShareContext = shareContext ? shareContext->fContext : nullptr;
- fContext = eglCreateContext(fDisplay, surfaceConfig, eglShareContext, contextAttribs);
+ fContext = eglCreateContext(fDisplay, surfaceConfig, eglShareContext, contextAttribs.data());
if (EGL_NO_CONTEXT == fContext) {
SkDebugf("Could not create context!");
this->destroyGLContext();
@@ -337,7 +347,6 @@ ANGLEGLContext::ANGLEGLContext(ANGLEBackend type, ANGLEContextVersion version,
break;
}
#endif
- const char* extensions = eglQueryString(fDisplay, EGL_EXTENSIONS);
if (strstr(extensions, "EGL_KHR_image")) {
fCreateImage = (PFNEGLCREATEIMAGEKHRPROC)eglGetProcAddress("eglCreateImageKHR");
fDestroyImage = (PFNEGLDESTROYIMAGEKHRPROC)eglGetProcAddress("eglDestroyImageKHR");
@@ -366,7 +375,7 @@ GrEGLImage ANGLEGLContext::texture2DToEGLImage(GrGLuint texID) const {
void ANGLEGLContext::destroyEGLImage(GrEGLImage image) const { fDestroyImage(fDisplay, image); }
GrGLuint ANGLEGLContext::eglImageToExternalTexture(GrEGLImage image) const {
- GrGLClearErr(this->gl());
+ while (this->gl()->fFunctions.fGetError() != GR_GL_NO_ERROR) {}
if (!this->gl()->hasExtension("GL_OES_EGL_image_external")) {
return 0;
}
@@ -382,12 +391,12 @@ GrGLuint ANGLEGLContext::eglImageToExternalTexture(GrEGLImage image) const {
return 0;
}
GR_GL_CALL(this->gl(), BindTexture(GR_GL_TEXTURE_EXTERNAL, texID));
- if (GR_GL_GET_ERROR(this->gl()) != GR_GL_NO_ERROR) {
+ if (this->gl()->fFunctions.fGetError() != GR_GL_NO_ERROR) {
GR_GL_CALL(this->gl(), DeleteTextures(1, &texID));
return 0;
}
glEGLImageTargetTexture2D(GR_GL_TEXTURE_EXTERNAL, image);
- if (GR_GL_GET_ERROR(this->gl()) != GR_GL_NO_ERROR) {
+ if (this->gl()->fFunctions.fGetError() != GR_GL_NO_ERROR) {
GR_GL_CALL(this->gl(), DeleteTextures(1, &texID));
return 0;
}
diff --git a/chromium/third_party/skia/tools/gpu/gl/egl/CreatePlatformGLTestContext_egl.cpp b/chromium/third_party/skia/tools/gpu/gl/egl/CreatePlatformGLTestContext_egl.cpp
index e3228a4e787..325e034a07e 100644
--- a/chromium/third_party/skia/tools/gpu/gl/egl/CreatePlatformGLTestContext_egl.cpp
+++ b/chromium/third_party/skia/tools/gpu/gl/egl/CreatePlatformGLTestContext_egl.cpp
@@ -375,7 +375,7 @@ void EGLGLTestContext::destroyEGLImage(GrEGLImage image) const {
GrGLuint EGLGLTestContext::eglImageToExternalTexture(GrEGLImage image) const {
#ifdef SK_GL
- GrGLClearErr(this->gl());
+ while (this->gl()->fFunctions.fGetError() != GR_GL_NO_ERROR) {}
if (!this->gl()->hasExtension("GL_OES_EGL_image_external")) {
return 0;
}
@@ -392,12 +392,12 @@ GrGLuint EGLGLTestContext::eglImageToExternalTexture(GrEGLImage image) const {
return 0;
}
GR_GL_CALL_NOERRCHECK(this->gl(), BindTexture(GR_GL_TEXTURE_EXTERNAL, texID));
- if (GR_GL_GET_ERROR(this->gl()) != GR_GL_NO_ERROR) {
+ if (this->gl()->fFunctions.fGetError() != GR_GL_NO_ERROR) {
GR_GL_CALL(this->gl(), DeleteTextures(1, &texID));
return 0;
}
glEGLImageTargetTexture2D(GR_GL_TEXTURE_EXTERNAL, image);
- if (GR_GL_GET_ERROR(this->gl()) != GR_GL_NO_ERROR) {
+ if (this->gl()->fFunctions.fGetError() != GR_GL_NO_ERROR) {
GR_GL_CALL(this->gl(), DeleteTextures(1, &texID));
return 0;
}
diff --git a/chromium/third_party/skia/tools/gpu/gl/interface/templates.go b/chromium/third_party/skia/tools/gpu/gl/interface/templates.go
index ebed908c67d..5f3e3918bce 100644
--- a/chromium/third_party/skia/tools/gpu/gl/interface/templates.go
+++ b/chromium/third_party/skia/tools/gpu/gl/interface/templates.go
@@ -234,6 +234,54 @@ GrGLInterface::GrGLInterface() {
fStandard = kNone_GrGLStandard;
}
+#if GR_GL_CHECK_ERROR
+static const char* get_error_string(GrGLenum err) {
+ switch (err) {
+ case GR_GL_NO_ERROR:
+ return "";
+ case GR_GL_INVALID_ENUM:
+ return "Invalid Enum";
+ case GR_GL_INVALID_VALUE:
+ return "Invalid Value";
+ case GR_GL_INVALID_OPERATION:
+ return "Invalid Operation";
+ case GR_GL_OUT_OF_MEMORY:
+ return "Out of Memory";
+ case GR_GL_CONTEXT_LOST:
+ return "Context Lost";
+ }
+ return "Unknown";
+}
+
+GrGLenum GrGLInterface::checkError(const char* location, const char* call) const {
+ GrGLenum error = fFunctions.fGetError();
+ if (error != GR_GL_NO_ERROR && !fSuppressErrorLogging) {
+ SkDebugf("---- glGetError 0x%x(%s)", error, get_error_string(error));
+ if (location) {
+ SkDebugf(" at\n\t%s", location);
+ }
+ if (call) {
+ SkDebugf("\n\t\t%s", call);
+ }
+ SkDebugf("\n");
+ if (error == GR_GL_OUT_OF_MEMORY) {
+ fOOMed = true;
+ }
+ }
+ return error;
+}
+
+bool GrGLInterface::checkAndResetOOMed() const {
+ if (fOOMed) {
+ fOOMed = false;
+ return true;
+ }
+ return false;
+}
+
+void GrGLInterface::suppressErrorLogging() { fSuppressErrorLogging = true; }
+#endif
+
#define RETURN_FALSE_INTERFACE \
SkDEBUGF("%s:%d GrGLInterface::validate() failed.\n", __FILE__, __LINE__); \
return false
diff --git a/chromium/third_party/skia/tools/gpu/vk/VkTestHelper.cpp b/chromium/third_party/skia/tools/gpu/vk/VkTestHelper.cpp
new file mode 100644
index 00000000000..f1a02a495fb
--- /dev/null
+++ b/chromium/third_party/skia/tools/gpu/vk/VkTestHelper.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2020 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "tools/gpu/vk/VkTestHelper.h"
+
+#ifdef SK_VULKAN
+
+#include "include/core/SkSurface.h"
+#include "include/gpu/GrContext.h"
+#include "tools/gpu/vk/VkTestUtils.h"
+
+#define ACQUIRE_INST_VK_PROC(name) \
+ fVk##name = reinterpret_cast<PFN_vk##name>(getProc("vk" #name, fBackendContext.fInstance,\
+ VK_NULL_HANDLE)); \
+ if (fVk##name == nullptr) { \
+ SkDebugf("Function ptr for vk%s could not be acquired\n", #name); \
+ return false; \
+ }
+
+#define ACQUIRE_DEVICE_VK_PROC(name) \
+ fVk##name = reinterpret_cast<PFN_vk##name>(getProc("vk" #name, VK_NULL_HANDLE, fDevice)); \
+ if (fVk##name == nullptr) { \
+ SkDebugf("Function ptr for vk%s could not be acquired\n", #name); \
+ return false; \
+ }
+
+bool VkTestHelper::init() {
+ PFN_vkGetInstanceProcAddr instProc;
+ PFN_vkGetDeviceProcAddr devProc;
+ if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc, &devProc)) {
+ return false;
+ }
+ auto getProc = [&instProc, &devProc](const char* proc_name,
+ VkInstance instance, VkDevice device) {
+ if (device != VK_NULL_HANDLE) {
+ return devProc(device, proc_name);
+ }
+ return instProc(instance, proc_name);
+ };
+
+ fFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
+ fFeatures.pNext = nullptr;
+
+ fBackendContext.fInstance = VK_NULL_HANDLE;
+ fBackendContext.fDevice = VK_NULL_HANDLE;
+
+ if (!sk_gpu_test::CreateVkBackendContext(getProc, &fBackendContext, &fExtensions,
+ &fFeatures, &fDebugCallback, nullptr,
+ sk_gpu_test::CanPresentFn(), fIsProtected)) {
+ return false;
+ }
+ fDevice = fBackendContext.fDevice;
+
+ if (fDebugCallback != VK_NULL_HANDLE) {
+ fDestroyDebugCallback = reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(
+ instProc(fBackendContext.fInstance, "vkDestroyDebugReportCallbackEXT"));
+ }
+ ACQUIRE_INST_VK_PROC(DestroyInstance)
+ ACQUIRE_INST_VK_PROC(DeviceWaitIdle)
+ ACQUIRE_INST_VK_PROC(DestroyDevice)
+
+ ACQUIRE_INST_VK_PROC(GetPhysicalDeviceFormatProperties)
+ ACQUIRE_INST_VK_PROC(GetPhysicalDeviceMemoryProperties)
+
+ ACQUIRE_DEVICE_VK_PROC(CreateImage)
+ ACQUIRE_DEVICE_VK_PROC(DestroyImage)
+ ACQUIRE_DEVICE_VK_PROC(GetImageMemoryRequirements)
+ ACQUIRE_DEVICE_VK_PROC(AllocateMemory)
+ ACQUIRE_DEVICE_VK_PROC(FreeMemory)
+ ACQUIRE_DEVICE_VK_PROC(BindImageMemory)
+ ACQUIRE_DEVICE_VK_PROC(MapMemory)
+ ACQUIRE_DEVICE_VK_PROC(UnmapMemory)
+ ACQUIRE_DEVICE_VK_PROC(FlushMappedMemoryRanges)
+ ACQUIRE_DEVICE_VK_PROC(GetImageSubresourceLayout)
+
+ fGrContext = GrContext::MakeVulkan(fBackendContext);
+ if (!fGrContext) {
+ return false;
+ }
+
+ return true;
+}
+
+void VkTestHelper::cleanup() {
+ fGrContext.reset();
+
+ fBackendContext.fMemoryAllocator.reset();
+ if (fDevice != VK_NULL_HANDLE) {
+ fVkDeviceWaitIdle(fDevice);
+ fVkDestroyDevice(fDevice, nullptr);
+ fDevice = VK_NULL_HANDLE;
+ }
+ if (fDebugCallback != VK_NULL_HANDLE) {
+ fDestroyDebugCallback(fBackendContext.fInstance, fDebugCallback, nullptr);
+ }
+
+ if (fBackendContext.fInstance != VK_NULL_HANDLE) {
+ fVkDestroyInstance(fBackendContext.fInstance, nullptr);
+ fBackendContext.fInstance = VK_NULL_HANDLE;
+ }
+
+ sk_gpu_test::FreeVulkanFeaturesStructs(&fFeatures);
+}
+
+#endif // SK_VULKAN
diff --git a/chromium/third_party/skia/tools/gpu/vk/VkTestHelper.h b/chromium/third_party/skia/tools/gpu/vk/VkTestHelper.h
new file mode 100644
index 00000000000..965885a1599
--- /dev/null
+++ b/chromium/third_party/skia/tools/gpu/vk/VkTestHelper.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2020 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef VkTestHelper_DEFINED
+#define VkTestHelper_DEFINED
+
+#include "include/core/SkTypes.h"
+
+#ifdef SK_VULKAN
+
+#include "include/core/SkRefCnt.h"
+#include "include/gpu/vk/GrVkBackendContext.h"
+#include "include/gpu/vk/GrVkExtensions.h"
+
+class GrContext;
+class SkSurface;
+
+#define DECLARE_VK_PROC(name) PFN_vk##name fVk##name
+
+class VkTestHelper {
+public:
+ VkTestHelper(bool isProtected) : fIsProtected(isProtected) {}
+
+ ~VkTestHelper() {
+ this->cleanup();
+ }
+
+ bool init();
+
+ GrContext* grContext() { return fGrContext.get(); }
+
+private:
+ void cleanup();
+
+ DECLARE_VK_PROC(DestroyInstance);
+ DECLARE_VK_PROC(DeviceWaitIdle);
+ DECLARE_VK_PROC(DestroyDevice);
+
+ DECLARE_VK_PROC(GetPhysicalDeviceFormatProperties);
+ DECLARE_VK_PROC(GetPhysicalDeviceMemoryProperties);
+
+ DECLARE_VK_PROC(CreateImage);
+ DECLARE_VK_PROC(DestroyImage);
+ DECLARE_VK_PROC(GetImageMemoryRequirements);
+ DECLARE_VK_PROC(AllocateMemory);
+ DECLARE_VK_PROC(FreeMemory);
+ DECLARE_VK_PROC(BindImageMemory);
+ DECLARE_VK_PROC(MapMemory);
+ DECLARE_VK_PROC(UnmapMemory);
+ DECLARE_VK_PROC(FlushMappedMemoryRanges);
+ DECLARE_VK_PROC(GetImageSubresourceLayout);
+
+ bool fIsProtected = false;
+ VkDevice fDevice = VK_NULL_HANDLE;
+
+ GrVkExtensions fExtensions;
+ VkPhysicalDeviceFeatures2 fFeatures = {};
+ VkDebugReportCallbackEXT fDebugCallback = VK_NULL_HANDLE;
+ PFN_vkDestroyDebugReportCallbackEXT fDestroyDebugCallback = nullptr;
+ GrVkBackendContext fBackendContext;
+ sk_sp<GrContext> fGrContext;
+};
+
+#undef DECLARE_VK_PROC
+
+#endif // SK_VULKAN
+#endif // VkTestHelper_DEFINED
diff --git a/chromium/third_party/skia/tools/gpu/vk/VkTestUtils.cpp b/chromium/third_party/skia/tools/gpu/vk/VkTestUtils.cpp
index a6026af739b..86084cf7935 100644
--- a/chromium/third_party/skia/tools/gpu/vk/VkTestUtils.cpp
+++ b/chromium/third_party/skia/tools/gpu/vk/VkTestUtils.cpp
@@ -110,6 +110,11 @@ VKAPI_ATTR VkBool32 VKAPI_CALL DebugReportCallback(
const char* pMessage,
void* pUserData) {
if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
+ // See https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/1887
+ if (strstr(pMessage, "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-01521") ||
+ strstr(pMessage, "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-01522")) {
+ return VK_FALSE;
+ }
SkDebugf("Vulkan error [%s]: code: %d: %s\n", pLayerPrefix, messageCode, pMessage);
print_backtrace();
SkDEBUGFAIL("Vulkan debug layer error");
diff --git a/chromium/third_party/skia/tools/gpu/vk/VkYcbcrSamplerHelper.cpp b/chromium/third_party/skia/tools/gpu/vk/VkYcbcrSamplerHelper.cpp
new file mode 100644
index 00000000000..6e464a1c8a9
--- /dev/null
+++ b/chromium/third_party/skia/tools/gpu/vk/VkYcbcrSamplerHelper.cpp
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2020 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "tools/gpu/vk/VkYcbcrSamplerHelper.h"
+
+#ifdef SK_VULKAN
+
+#include "include/gpu/GrContext.h"
+#include "src/gpu/GrContextPriv.h"
+#include "src/gpu/vk/GrVkGpu.h"
+#include "src/gpu/vk/GrVkUtil.h"
+
+int VkYcbcrSamplerHelper::GetExpectedY(int x, int y, int width, int height) {
+ return 16 + (x + y) * 219 / (width + height - 2);
+}
+
+std::pair<int, int> VkYcbcrSamplerHelper::GetExpectedUV(int x, int y, int width, int height) {
+ return { 16 + x * 224 / (width - 1), 16 + y * 224 / (height - 1) };
+}
+
+GrVkGpu* VkYcbcrSamplerHelper::vkGpu() {
+ return (GrVkGpu*) fContext->priv().getGpu();
+}
+
+VkYcbcrSamplerHelper::VkYcbcrSamplerHelper(GrContext* context) : fContext(context) {
+ SkASSERT_RELEASE(context->backend() == GrBackendApi::kVulkan);
+}
+
+VkYcbcrSamplerHelper::~VkYcbcrSamplerHelper() {
+ GrVkGpu* vkGpu = this->vkGpu();
+
+ if (fImage != VK_NULL_HANDLE) {
+ GR_VK_CALL(vkGpu->vkInterface(), DestroyImage(vkGpu->device(), fImage, nullptr));
+ fImage = VK_NULL_HANDLE;
+ }
+ if (fImageMemory != VK_NULL_HANDLE) {
+ GR_VK_CALL(vkGpu->vkInterface(), FreeMemory(vkGpu->device(), fImageMemory, nullptr));
+ fImageMemory = VK_NULL_HANDLE;
+ }
+}
+
+bool VkYcbcrSamplerHelper::isYCbCrSupported() {
+ GrVkGpu* vkGpu = this->vkGpu();
+
+ return vkGpu->vkCaps().supportsYcbcrConversion();
+}
+
+bool VkYcbcrSamplerHelper::createBackendTexture(uint32_t width, uint32_t height) {
+ GrVkGpu* vkGpu = this->vkGpu();
+ VkResult result;
+
+ // Verify that the image format is supported.
+ VkFormatProperties formatProperties;
+ GR_VK_CALL(vkGpu->vkInterface(),
+ GetPhysicalDeviceFormatProperties(vkGpu->physicalDevice(),
+ VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
+ &formatProperties));
+ if (!(formatProperties.linearTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
+ // VK_FORMAT_G8_B8R8_2PLANE_420_UNORM is not supported
+ return false;
+ }
+
+ // Create YCbCr image.
+ VkImageCreateInfo vkImageInfo = {};
+ vkImageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+ vkImageInfo.imageType = VK_IMAGE_TYPE_2D;
+ vkImageInfo.format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
+ vkImageInfo.extent = VkExtent3D{width, height, 1};
+ vkImageInfo.mipLevels = 1;
+ vkImageInfo.arrayLayers = 1;
+ vkImageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
+ vkImageInfo.tiling = VK_IMAGE_TILING_LINEAR;
+ vkImageInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
+ vkImageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+ vkImageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+
+ SkASSERT(fImage == VK_NULL_HANDLE);
+ GR_VK_CALL_RESULT(vkGpu, result, CreateImage(vkGpu->device(), &vkImageInfo, nullptr, &fImage));
+ if (result != VK_SUCCESS) {
+ return false;
+ }
+
+ VkMemoryRequirements requirements;
+ GR_VK_CALL(vkGpu->vkInterface(), GetImageMemoryRequirements(vkGpu->device(),
+ fImage,
+ &requirements));
+
+ uint32_t memoryTypeIndex = 0;
+ bool foundHeap = false;
+ VkPhysicalDeviceMemoryProperties phyDevMemProps;
+ GR_VK_CALL(vkGpu->vkInterface(), GetPhysicalDeviceMemoryProperties(vkGpu->physicalDevice(),
+ &phyDevMemProps));
+ for (uint32_t i = 0; i < phyDevMemProps.memoryTypeCount && !foundHeap; ++i) {
+ if (requirements.memoryTypeBits & (1 << i)) {
+ // Map host-visible memory.
+ if (phyDevMemProps.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
+ memoryTypeIndex = i;
+ foundHeap = true;
+ }
+ }
+ }
+ if (!foundHeap) {
+ return false;
+ }
+
+ VkMemoryAllocateInfo allocInfo = {};
+ allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+ allocInfo.allocationSize = requirements.size;
+ allocInfo.memoryTypeIndex = memoryTypeIndex;
+
+ SkASSERT(fImageMemory == VK_NULL_HANDLE);
+ GR_VK_CALL_RESULT(vkGpu, result, AllocateMemory(vkGpu->device(), &allocInfo,
+ nullptr, &fImageMemory));
+ if (result != VK_SUCCESS) {
+ return false;
+ }
+
+ void* mappedBuffer;
+ GR_VK_CALL_RESULT(vkGpu, result, MapMemory(vkGpu->device(), fImageMemory, 0u,
+ requirements.size, 0u, &mappedBuffer));
+ if (result != VK_SUCCESS) {
+ return false;
+ }
+
+ // Write Y channel.
+ VkImageSubresource subresource;
+ subresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
+ subresource.mipLevel = 0;
+ subresource.arrayLayer = 0;
+
+ VkSubresourceLayout yLayout;
+ GR_VK_CALL(vkGpu->vkInterface(), GetImageSubresourceLayout(vkGpu->device(), fImage,
+ &subresource, &yLayout));
+ uint8_t* bufferData = reinterpret_cast<uint8_t*>(mappedBuffer) + yLayout.offset;
+ for (size_t y = 0; y < height; ++y) {
+ for (size_t x = 0; x < width; ++x) {
+ bufferData[y * yLayout.rowPitch + x] = GetExpectedY(x, y, width, height);
+ }
+ }
+
+ // Write UV channels.
+ subresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
+ VkSubresourceLayout uvLayout;
+ GR_VK_CALL(vkGpu->vkInterface(), GetImageSubresourceLayout(vkGpu->device(), fImage,
+ &subresource, &uvLayout));
+ bufferData = reinterpret_cast<uint8_t*>(mappedBuffer) + uvLayout.offset;
+ for (size_t y = 0; y < height / 2; ++y) {
+ for (size_t x = 0; x < width / 2; ++x) {
+ auto [u, v] = GetExpectedUV(2*x, 2*y, width, height);
+ bufferData[y * uvLayout.rowPitch + x * 2] = u;
+ bufferData[y * uvLayout.rowPitch + x * 2 + 1] = v;
+ }
+ }
+
+ VkMappedMemoryRange flushRange;
+ flushRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
+ flushRange.pNext = nullptr;
+ flushRange.memory = fImageMemory;
+ flushRange.offset = 0;
+ flushRange.size = VK_WHOLE_SIZE;
+ GR_VK_CALL_RESULT(vkGpu, result, FlushMappedMemoryRanges(vkGpu->device(), 1, &flushRange));
+ if (result != VK_SUCCESS) {
+ return false;
+ }
+ GR_VK_CALL(vkGpu->vkInterface(), UnmapMemory(vkGpu->device(), fImageMemory));
+
+ // Bind image memory.
+ GR_VK_CALL_RESULT(vkGpu, result, BindImageMemory(vkGpu->device(), fImage, fImageMemory, 0u));
+ if (result != VK_SUCCESS) {
+ return false;
+ }
+
+ // Wrap the image into SkImage.
+ GrVkYcbcrConversionInfo ycbcrInfo(vkImageInfo.format,
+ /*externalFormat=*/0,
+ VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709,
+ VK_SAMPLER_YCBCR_RANGE_ITU_NARROW,
+ VK_CHROMA_LOCATION_COSITED_EVEN,
+ VK_CHROMA_LOCATION_COSITED_EVEN,
+ VK_FILTER_LINEAR,
+ false,
+ formatProperties.linearTilingFeatures);
+ GrVkAlloc alloc(fImageMemory, 0 /* offset */, requirements.size, 0 /* flags */);
+ GrVkImageInfo imageInfo(fImage, alloc, VK_IMAGE_TILING_LINEAR, VK_IMAGE_LAYOUT_UNDEFINED,
+ vkImageInfo.format, 1 /* levelCount */, VK_QUEUE_FAMILY_IGNORED,
+ GrProtected::kNo, ycbcrInfo);
+
+ fTexture = GrBackendTexture(width, height, imageInfo);
+ return true;
+}
+
+#endif // SK_VULKAN
diff --git a/chromium/third_party/skia/tools/gpu/vk/VkYcbcrSamplerHelper.h b/chromium/third_party/skia/tools/gpu/vk/VkYcbcrSamplerHelper.h
new file mode 100644
index 00000000000..929f4c94e87
--- /dev/null
+++ b/chromium/third_party/skia/tools/gpu/vk/VkYcbcrSamplerHelper.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2020 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef VkYcbcrSamplerHelper_DEFINED
+#define VkYcbcrSamplerHelper_DEFINED
+
+#include "include/core/SkTypes.h"
+
+#ifdef SK_VULKAN
+
+#include "include/gpu/GrBackendSurface.h"
+
+class GrContext;
+class GrVkGpu;
+
+// This helper will create and hold data for a Vulkan YCbCr backend texture. This format is
+// particularly interesting because its sampler is immutable.
+class VkYcbcrSamplerHelper {
+public:
+ VkYcbcrSamplerHelper(GrContext*);
+ ~VkYcbcrSamplerHelper();
+
+ bool isYCbCrSupported();
+
+ bool createBackendTexture(uint32_t width, uint32_t height);
+
+ const GrBackendTexture& backendTexture() const { return fTexture; }
+
+ static int GetExpectedY(int x, int y, int width, int height);
+ static std::pair<int, int> GetExpectedUV(int x, int y, int width, int height);
+
+private:
+ GrVkGpu* vkGpu();
+
+ GrContext* fContext;
+
+ VkImage fImage = VK_NULL_HANDLE;
+ VkDeviceMemory fImageMemory = VK_NULL_HANDLE;
+ GrBackendTexture fTexture;
+};
+
+#endif // SK_VULKAN
+
+#endif // VkYcbcrSamplerHelper_DEFINED