diff options
Diffstat (limited to 'chromium/third_party/skia/tools/gpu')
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 |