diff options
author | Greg Daniel <egdaniel@google.com> | 2017-11-18 13:31:59 +0000 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-11-18 13:32:08 +0000 |
commit | 9c2202ffc22b4293b48a4edeafa1b5d2bab8bb83 (patch) | |
tree | 6667b8892e760ba70baa81f55a36c974eeb31761 | |
parent | c12853ae42c30ef1cffb77c7777b330a7bbdb603 (diff) |
Revert "Add Atlas Text interface for rendering SDF glyphs."
This reverts commit 39631f3df172feb385527a5d125bc53b0bded7e6.
Reason for revert: break google3 rool
Original change's description:
> Add Atlas Text interface for rendering SDF glyphs.
>
> This new API is built upon SDF text atlas code from the GPU backend. Unlike using the GPU
> backend to draw text, this set of interfaces allows the client to render the SDF glyphs. The
> client issues text draws to potentially multiple targets and then the client flushes. The
> client then gets commands from Skia with data to put into a texture atlas and vertices to
> draw that reference the texture. The client is responsible for creating the texture, uploading
> the SDF data to the texture, and drawing the vertices provided by Skia.
>
> Change-Id: Ie9447e19b85f0ce1c2b942e5216c787a74f335d3
> Reviewed-on: https://skia-review.googlesource.com/59360
> Commit-Queue: Brian Salomon <bsalomon@google.com>
> Reviewed-by: Robert Phillips <robertphillips@google.com>
TBR=jvanverth@google.com,bsalomon@google.com,robertphillips@google.com
Change-Id: I4aad0c99e645b476fd8ba25731f2a10e8802bb25
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://skia-review.googlesource.com/73420
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
-rw-r--r-- | BUILD.gn | 13 | ||||
-rw-r--r-- | gm/atlastext.cpp | 123 | ||||
-rw-r--r-- | gn/core.gni | 1 | ||||
-rw-r--r-- | gn/gm.gni | 1 | ||||
-rw-r--r-- | gn/gpu.gni | 11 | ||||
-rw-r--r-- | include/atlastext/SkAtlasTextContext.h | 42 | ||||
-rw-r--r-- | include/atlastext/SkAtlasTextFont.h | 35 | ||||
-rw-r--r-- | include/atlastext/SkAtlasTextRenderer.h | 71 | ||||
-rw-r--r-- | include/atlastext/SkAtlasTextTarget.h | 61 | ||||
-rw-r--r-- | include/core/SkPostConfig.h | 6 | ||||
-rw-r--r-- | src/atlastext/SkAtlasTextContext.cpp | 17 | ||||
-rw-r--r-- | src/atlastext/SkAtlasTextTarget.cpp | 143 | ||||
-rw-r--r-- | src/atlastext/SkInternalAtlasTextContext.cpp | 117 | ||||
-rw-r--r-- | src/atlastext/SkInternalAtlasTextContext.h | 80 | ||||
-rw-r--r-- | src/core/SkArenaAlloc.h | 6 | ||||
-rw-r--r-- | src/core/SkArenaAllocList.h | 79 | ||||
-rw-r--r-- | src/gpu/GrOpFlushState.cpp | 19 | ||||
-rw-r--r-- | src/gpu/GrOpFlushState.h | 58 | ||||
-rw-r--r-- | src/gpu/ops/GrAtlasTextOp.h | 26 | ||||
-rw-r--r-- | tools/gpu/atlastext/GLTestAtlasTextRenderer.cpp | 439 | ||||
-rw-r--r-- | tools/gpu/atlastext/GLTestAtlasTextRenderer.h | 25 | ||||
-rw-r--r-- | tools/gpu/atlastext/TestAtlasTextRenderer.h | 34 | ||||
-rw-r--r-- | tools/gpu/gl/glx/CreatePlatformGLTestContext_glx.cpp | 5 |
23 files changed, 84 insertions, 1328 deletions
@@ -52,7 +52,6 @@ declare_args() { declare_args() { skia_use_dng_sdk = !is_fuchsia && skia_use_libjpeg_turbo && skia_use_zlib skia_use_sfntly = skia_use_icu - skia_enable_atlas_text = is_skia_dev_build && skia_enable_gpu if (is_android) { skia_use_vulkan = defined(ndk_api) && ndk_api >= 24 @@ -93,7 +92,6 @@ skia_public_includes = [ "include/encode", "include/gpu", "include/gpu/gl", - "include/atlastext", "include/pathops", "include/ports", "include/svg", @@ -104,9 +102,6 @@ skia_public_includes = [ if (skia_use_vulkan) { skia_public_includes += [ "include/gpu/vk" ] } -if (skia_enable_atlas_text) { - skia_public_includes += [ "include/atlastext" ] -} if (skia_use_metal) { skia_public_includes += [ "include/gpu/mtl" ] } @@ -130,9 +125,6 @@ config("skia_public") { if (!skia_enable_gpu) { defines += [ "SK_SUPPORT_GPU=0" ] } - if (skia_enable_atlas_text) { - defines += [ "SK_SUPPORT_ATLAS_TEXT=1" ] - } } # Skia internal APIs, used by Skia itself and a few test tools. @@ -594,10 +586,6 @@ optional("gpu") { libs += [ "Metal.framework" ] cflags_objcc += [ "-fobjc-arc" ] } - - if (skia_enable_atlas_text) { - sources += skia_atlas_text_sources - } } optional("heif") { @@ -1004,7 +992,6 @@ if (skia_enable_tools) { "tools/gpu/GrContextFactory.cpp", "tools/gpu/GrTest.cpp", "tools/gpu/TestContext.cpp", - "tools/gpu/atlastext/GLTestAtlasTextRenderer.cpp", "tools/gpu/gl/GLTestContext.cpp", "tools/gpu/gl/command_buffer/GLTestContext_command_buffer.cpp", "tools/gpu/gl/debug/DebugGLTestContext.cpp", diff --git a/gm/atlastext.cpp b/gm/atlastext.cpp deleted file mode 100644 index b8acb0fcc7..0000000000 --- a/gm/atlastext.cpp +++ /dev/null @@ -1,123 +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 "gm.h" - -#if SK_SUPPORT_ATLAS_TEXT - -#include "SkAtlasTextContext.h" -#include "SkAtlasTextFont.h" -#include "SkAtlasTextTarget.h" -#include "SkBitmap.h" -#include "SkCanvas.h" -#include "SkTypeface.h" -#include "gpu/TestContext.h" -#include "gpu/atlastext/GLTestAtlasTextRenderer.h" -#include "gpu/atlastext/TestAtlasTextRenderer.h" -#include "sk_tool_utils.h" - -// GM that draws text using the Atlas Text interface offscreen and then blits that to the canvas. - -static SkScalar draw_string(SkAtlasTextTarget* target, const SkString& text, SkScalar x, SkScalar y, - uint32_t color, sk_sp<SkTypeface> typeface, float size) { - auto font = SkAtlasTextFont::Make(std::move(typeface), size); - target->drawText(text.c_str(), text.size(), x, y, color, *font); - SkPaint paint; - paint.setTextSize(size); - return x + paint.measureText(text.c_str(), text.size()); -} - -class AtlasTextGM : public skiagm::GM { -public: - AtlasTextGM() = default; - -protected: - SkString onShortName() override { return SkString("atlastext"); } - - SkISize onISize() override { return SkISize::Make(kSize, kSize); } - - void onOnceBeforeDraw() override { - fRenderer = sk_gpu_test::MakeGLTestAtlasTextRenderer(); - if (!fRenderer) { - return; - } - fContext = SkAtlasTextContext::Make(fRenderer); - auto targetHandle = fRenderer->makeTargetHandle(kSize, kSize); - fTarget = SkAtlasTextTarget::Make(fContext, kSize, kSize, targetHandle); - - fTypefaces[0] = sk_tool_utils::create_portable_typeface("serif", SkFontStyle::Italic()); - fTypefaces[1] = - sk_tool_utils::create_portable_typeface("sans-serif", SkFontStyle::Italic()); - fTypefaces[2] = sk_tool_utils::create_portable_typeface("serif", SkFontStyle::Normal()); - fTypefaces[3] = - sk_tool_utils::create_portable_typeface("sans-serif", SkFontStyle::Normal()); - fTypefaces[4] = sk_tool_utils::create_portable_typeface("serif", SkFontStyle::Bold()); - fTypefaces[5] = sk_tool_utils::create_portable_typeface("sans-serif", SkFontStyle::Bold()); - } - - void onDraw(SkCanvas* canvas) override { - if (!fRenderer) { - canvas->clear(SK_ColorRED); - return; - } - auto bmp = this->drawText(); - SkPaint paint; - paint.setBlendMode(SkBlendMode::kSrc); - canvas->drawBitmap(bmp, 0, 0); - } - -private: - SkBitmap drawText() { - static const int kSizes[] = {8, 13, 18, 23, 30}; - - static const SkString kTexts[] = {SkString("ABCDEFGHIJKLMNOPQRSTUVWXYZ"), - SkString("abcdefghijklmnopqrstuvwxyz"), - SkString("0123456789"), - SkString("!@#$%^&*()<>[]{}")}; - SkScalar x = 0; - SkScalar y = 10; - - SkRandom random; - do { - for (auto s : kSizes) { - auto size = 2 * s; - for (const auto& typeface : fTypefaces) { - for (const auto& text : kTexts) { - uint32_t color = random.nextU(); - x = size + draw_string(fTarget.get(), text, x, y, color, typeface, size); - x = SkScalarCeilToScalar(x); - if (x + 100 > kSize) { - x = 0; - y += SkScalarCeilToScalar(size + 3); - if (y > kSize) { - fTarget->flush(); - return fRenderer->readTargetHandle(fTarget->handle()); - } - } - } - } - } - } while (true); - } - - static constexpr int kSize = 1280; - - sk_sp<SkTypeface> fTypefaces[6]; - sk_sp<sk_gpu_test::TestAtlasTextRenderer> fRenderer; - std::unique_ptr<SkAtlasTextTarget> fTarget; - sk_sp<SkAtlasTextContext> fContext; - - typedef GM INHERITED; -}; - -constexpr int AtlasTextGM::kSize; - -////////////////////////////////////////////////////////////////////////////// - -DEF_GM(return new AtlasTextGM;) - -#endif diff --git a/gn/core.gni b/gn/core.gni index 259cd191f4..186e5af454 100644 --- a/gn/core.gni +++ b/gn/core.gni @@ -134,7 +134,6 @@ skia_core_sources = [ "$_src/core/SkFindAndPlaceGlyph.h", "$_src/core/SkArenaAlloc.cpp", "$_src/core/SkArenaAlloc.h", - "$_src/core/SkArenaAllocList.h", "$_src/core/SkGaussFilter.cpp", "$_src/core/SkGaussFilter.h", "$_src/core/SkFlattenable.cpp", @@ -22,7 +22,6 @@ gm_sources = [ "$_gm/arcofzorro.cpp", "$_gm/arcto.cpp", "$_gm/arithmode.cpp", - "$_gm/atlastext.cpp", "$_gm/badpaint.cpp", "$_gm/beziereffects.cpp", "$_gm/beziers.cpp", diff --git a/gn/gpu.gni b/gn/gpu.gni index a26111dbc3..e584bf5187 100644 --- a/gn/gpu.gni +++ b/gn/gpu.gni @@ -628,14 +628,3 @@ skia_native_gpu_sources = [ "$_src/gpu/gl/iOS/GrGLCreateNativeInterface_iOS.cpp", "$_src/gpu/gl/android/GrGLCreateNativeInterface_android.cpp", ] - -skia_atlas_text_sources = [ - "$_include/atlastext/SkAtlasTextContext.h", - "$_include/atlastext/SkAtlasTextFont.h", - "$_include/atlastext/SkAtlasTextRenderer.h", - "$_include/atlastext/SkAtlasTextTarget.h", - - "$_src/atlastext/SkAtlasTextContext.cpp", - "$_src/atlastext/SkAtlasTextTarget.cpp", - "$_src/atlastext/SkInternalAtlasTextContext.cpp", -] diff --git a/include/atlastext/SkAtlasTextContext.h b/include/atlastext/SkAtlasTextContext.h deleted file mode 100644 index bb5de52992..0000000000 --- a/include/atlastext/SkAtlasTextContext.h +++ /dev/null @@ -1,42 +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 SkAtlasTextContext_DEFINED -#define SkAtlasTextContext_DEFINED - -#include "SkRefCnt.h" - -class SkAtlasTextRenderer; -class SkInternalAtlasTextContext; - -SkAtlasTextRenderer* SkGetAtlasTextRendererFromInternalContext(class SkInternalAtlasTextContext&); - -/** - * Class that Atlas Text client uses to register their SkAtlasTextRenderer implementation and - * to create one or more SkAtlasTextTargets (destination surfaces for text rendering). - */ -class SK_API SkAtlasTextContext : public SkRefCnt { -public: - static sk_sp<SkAtlasTextContext> Make(sk_sp<SkAtlasTextRenderer>); - - SkAtlasTextRenderer* renderer() const { - return SkGetAtlasTextRendererFromInternalContext(*fInternalContext); - } - - SkInternalAtlasTextContext& internal() { return *fInternalContext; } - -private: - SkAtlasTextContext() = delete; - SkAtlasTextContext(const SkAtlasTextContext&) = delete; - SkAtlasTextContext& operator=(const SkAtlasTextContext&) = delete; - - SkAtlasTextContext(sk_sp<SkAtlasTextRenderer>); - - std::unique_ptr<SkInternalAtlasTextContext> fInternalContext; -}; - -#endif diff --git a/include/atlastext/SkAtlasTextFont.h b/include/atlastext/SkAtlasTextFont.h deleted file mode 100644 index a9e641f7ad..0000000000 --- a/include/atlastext/SkAtlasTextFont.h +++ /dev/null @@ -1,35 +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 SkAtlasTextFont_DEFINED -#define SkAtlasTextFont_DEFINED - -#include "SkRefCnt.h" -#include "SkTypeface.h" - -/** Represents a font at a size. TODO: What else do we need here (skewX, scaleX, vertical, ...)? */ -class SK_API SkAtlasTextFont : public SkRefCnt { -public: - static sk_sp<SkAtlasTextFont> Make(sk_sp<SkTypeface> typeface, SkScalar size) { - return sk_sp<SkAtlasTextFont>(new SkAtlasTextFont(std::move(typeface), size)); - } - - SkTypeface* typeface() const { return fTypeface.get(); } - - sk_sp<SkTypeface> refTypeface() const { return fTypeface; } - - SkScalar size() const { return fSize; } - -private: - SkAtlasTextFont(sk_sp<SkTypeface> typeface, SkScalar size) - : fTypeface(std::move(typeface)), fSize(size) {} - - sk_sp<SkTypeface> fTypeface; - SkScalar fSize; -}; - -#endif diff --git a/include/atlastext/SkAtlasTextRenderer.h b/include/atlastext/SkAtlasTextRenderer.h deleted file mode 100644 index a78e270edb..0000000000 --- a/include/atlastext/SkAtlasTextRenderer.h +++ /dev/null @@ -1,71 +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 "SkPoint.h" -#include "SkRefCnt.h" - -#ifndef SkAtlasTextRenderer_DEFINED -#define SkAtlasTextRenderer_DEFINED - -/** - * This is the base class for a renderer implemented by the SkAtlasText client. The - * SkAtlasTextContext issues texture creations, deletions, uploads, and vertex draws to the - * renderer. The renderer must perform those actions in the order called to correctly render - * the text drawn to SkAtlasTextTargets. - */ -class SK_API SkAtlasTextRenderer : public SkRefCnt { -public: - enum class AtlasFormat { - /** Unsigned normalized 8 bit single channel format. */ - kA8 - }; - - struct SDFVertex { - /** Position in device space (not normalized). */ - SkPoint fPosition; - /** Color, same value for all four corners of a glyph quad. */ - uint32_t fColor; - /** Texture coordinate (in texel units, not normalized). */ - SkIPoint16 fTextureCoord; - }; - - virtual ~SkAtlasTextRenderer() = default; - - /** - * Create a texture of the provided format with dimensions 'width' x 'height' - * and return a unique handle. - */ - virtual void* createTexture(AtlasFormat, int width, int height) = 0; - - /** - * Delete the texture with the passed handle. - */ - virtual void deleteTexture(void* textureHandle) = 0; - - /** - * Place the pixel data specified by 'data' in the texture with handle - * 'textureHandle' in the rectangle ['x', 'x' + 'width') x ['y', 'y' + 'height'). - * 'rowBytes' specifies the byte offset between successive rows in 'data' and will always be - * a multiple of the number of bytes per pixel. - * The pixel format of data is the same as that of 'textureHandle'. - */ - virtual void setTextureData(void* textureHandle, const void* data, int x, int y, int width, - int height, size_t rowBytes) = 0; - - /** - * Draws glyphs using SDFs. The SDF data resides in 'textureHandle'. The array - * 'vertices' provides interleaved device-space positions, colors, and - * texture coordinates. There are are 4 * 'quadCnt' entries in 'vertices'. - */ - virtual void drawSDFGlyphs(void* targetHandle, void* textureHandle, const SDFVertex vertices[], - int quadCnt) = 0; - - /** Called when a SkAtlasTextureTarget is destroyed. */ - virtual void targetDeleted(void* targetHandle) = 0; -}; - -#endif diff --git a/include/atlastext/SkAtlasTextTarget.h b/include/atlastext/SkAtlasTextTarget.h deleted file mode 100644 index 0859afde39..0000000000 --- a/include/atlastext/SkAtlasTextTarget.h +++ /dev/null @@ -1,61 +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 SkAtlasTextTarget_DEFINED -#define SkAtlasTextTarget_DEFINED - -#include <memory> -#include "SkRefCnt.h" -#include "SkScalar.h" - -class SkAtlasTextContext; -class SkAtlasTextFont; - -/** Represents a client-created renderable surface and is used to draw text into the surface. */ -class SK_API SkAtlasTextTarget { -public: - virtual ~SkAtlasTextTarget(); - - /** - * Creates a text drawing target. ‘handle’ is used to identify this rendering surface when - * draws are flushed to the SkAtlasTextContext's SkAtlasTextRenderer. - */ - static std::unique_ptr<SkAtlasTextTarget> Make(sk_sp<SkAtlasTextContext>, int width, int height, - void* handle); - - /** - * Enqueues a text draw in the target. The meaning of 'color' here is interpreted by the - * client's SkAtlasTextRenderer when it actually renders the text. - */ - virtual void drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, - uint32_t color, const SkAtlasTextFont& font) = 0; - - /** Issues all queued text draws to SkAtlasTextRenderer. */ - virtual void flush() = 0; - - int width() const { return fWidth; } - int height() const { return fHeight; } - - void* handle() const { return fHandle; } - - SkAtlasTextContext* context() const { return fContext.get(); } - -protected: - SkAtlasTextTarget(sk_sp<SkAtlasTextContext>, int width, int height, void* handle); - - void* const fHandle; - const sk_sp<SkAtlasTextContext> fContext; - const int fWidth; - const int fHeight; - -private: - SkAtlasTextTarget() = delete; - SkAtlasTextTarget(const SkAtlasTextContext&) = delete; - SkAtlasTextTarget& operator=(const SkAtlasTextContext&) = delete; -}; - -#endif diff --git a/include/core/SkPostConfig.h b/include/core/SkPostConfig.h index ce81904452..3a39f66c8f 100644 --- a/include/core/SkPostConfig.h +++ b/include/core/SkPostConfig.h @@ -89,12 +89,6 @@ # define SK_SUPPORT_GPU 1 #endif -#if !defined(SK_SUPPORT_ATLAS_TEXT) -# define SK_SUPPORT_ATLAS_TEXT 0 -#elif SK_SUPPORT_ATLAS_TEXT && !SK_SUPPORT_GPU -# error "SK_SUPPORT_ATLAS_TEXT requires SK_SUPPORT_GPU" -#endif - /** * The clang static analyzer likes to know that when the program is not * expected to continue (crash, assertion failure, etc). It will notice that diff --git a/src/atlastext/SkAtlasTextContext.cpp b/src/atlastext/SkAtlasTextContext.cpp deleted file mode 100644 index 85e79118ee..0000000000 --- a/src/atlastext/SkAtlasTextContext.cpp +++ /dev/null @@ -1,17 +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 "SkAtlasTextContext.h" -#include "SkAtlasTextRenderer.h" -#include "SkInternalAtlasTextContext.h" - -sk_sp<SkAtlasTextContext> SkAtlasTextContext::Make(sk_sp<SkAtlasTextRenderer> renderer) { - return sk_sp<SkAtlasTextContext>(new SkAtlasTextContext(std::move(renderer))); -} - -SkAtlasTextContext::SkAtlasTextContext(sk_sp<SkAtlasTextRenderer> renderer) - : fInternalContext(SkInternalAtlasTextContext::Make(std::move(renderer))) {} diff --git a/src/atlastext/SkAtlasTextTarget.cpp b/src/atlastext/SkAtlasTextTarget.cpp deleted file mode 100644 index 57ece37b4f..0000000000 --- a/src/atlastext/SkAtlasTextTarget.cpp +++ /dev/null @@ -1,143 +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 "SkAtlasTextTarget.h" -#include "GrClip.h" -#include "SkAtlasTextContext.h" -#include "SkAtlasTextFont.h" -#include "SkAtlasTextRenderer.h" -#include "SkGr.h" -#include "SkInternalAtlasTextContext.h" -#include "ops/GrAtlasTextOp.h" -#include "text/GrAtlasTextContext.h" - -SkAtlasTextTarget::SkAtlasTextTarget(sk_sp<SkAtlasTextContext> context, int width, int height, - void* handle) - : fHandle(handle), fContext(std::move(context)), fWidth(width), fHeight(height) {} - -SkAtlasTextTarget::~SkAtlasTextTarget() { fContext->renderer()->targetDeleted(fHandle); } - -////////////////////////////////////////////////////////////////////////////// - -static const GrColorSpaceInfo kColorSpaceInfo(nullptr, kRGBA_8888_GrPixelConfig); - -////////////////////////////////////////////////////////////////////////////// - -class SkInternalAtlasTextTarget : public GrTextUtils::Target, public SkAtlasTextTarget { -public: - SkInternalAtlasTextTarget(sk_sp<SkAtlasTextContext> context, int width, int height, - void* handle) - : GrTextUtils::Target(width, height, kColorSpaceInfo) - , SkAtlasTextTarget(std::move(context), width, height, handle) {} - - /** GrTextUtils::Target overrides */ - - void addDrawOp(const GrClip&, std::unique_ptr<GrAtlasTextOp> op) override; - - void drawPath(const GrClip&, const SkPath&, const SkPaint&, const SkMatrix& viewMatrix, - const SkMatrix* pathMatrix, const SkIRect& clipBounds) override { - SkDebugf("Path glyph??"); - } - - void makeGrPaint(GrMaskFormat, const SkPaint& skPaint, const SkMatrix&, - GrPaint* grPaint) override { - grPaint->setColor4f(SkColorToPremulGrColor4fLegacy(skPaint.getColor())); - } - - /** SkAtlasTextTarget overrides */ - - void drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, uint32_t color, - const SkAtlasTextFont&) override; - void flush() override; - -private: - uint32_t fColor; - using SkAtlasTextTarget::fWidth; - using SkAtlasTextTarget::fHeight; - struct RecordedOp { - std::unique_ptr<GrAtlasTextOp> fOp; - uint32_t fColor; - }; - SkTArray<RecordedOp, true> fOps; -}; - -////////////////////////////////////////////////////////////////////////////// - -std::unique_ptr<SkAtlasTextTarget> SkAtlasTextTarget::Make(sk_sp<SkAtlasTextContext> context, - int width, int height, void* handle) { - return std::unique_ptr<SkAtlasTextTarget>( - new SkInternalAtlasTextTarget(std::move(context), width, height, handle)); -} - -////////////////////////////////////////////////////////////////////////////// - -#include "GrContextPriv.h" -#include "GrDrawingManager.h" - -void SkInternalAtlasTextTarget::drawText(const void* text, size_t byteLength, SkScalar x, - SkScalar y, uint32_t color, const SkAtlasTextFont& font) { - SkPaint paint; - paint.setAntiAlias(true); - paint.setTypeface(font.refTypeface()); - paint.setTextSize(font.size()); - paint.setStyle(SkPaint::kFill_Style); - - // TODO: Figure out what if anything to do with these: - // Paint setTextEncoding? Font isEnableByteCodeHints()? Font isUseNonLinearMetrics()? - - // The atlas text context does munging of the paint color. We store the client's color here - // and the context will write it into the final vertices given to the client's renderer. - fColor = color; - - // The pixel geometry here is arbitrary. We don't draw LCD text. - SkSurfaceProps props(SkSurfaceProps::kUseDistanceFieldFonts_Flag, kUnknown_SkPixelGeometry); - auto* grContext = this->context()->internal().grContext(); - auto bounds = SkIRect::MakeWH(fWidth, fHeight); - auto atlasTextContext = grContext->contextPriv().drawingManager()->getAtlasTextContext(); - atlasTextContext->drawText(grContext, this, GrNoClip(), paint, SkMatrix::I(), props, - (const char*)text, byteLength, x, y, bounds); -} - -void SkInternalAtlasTextTarget::addDrawOp(const GrClip& clip, std::unique_ptr<GrAtlasTextOp> op) { - SkASSERT(clip.quickContains(SkRect::MakeIWH(fWidth, fHeight))); - // The SkAtlasTextRenderer currently only handles grayscale SDF glyphs. - if (op->maskType() != GrAtlasTextOp::kGrayscaleDistanceField_MaskType) { - return; - } - // TODO: batch ops here. - op->visitProxies([](GrSurfaceProxy*) {}); - fOps.emplace_back(RecordedOp{std::move(op), fColor}); -} - -void SkInternalAtlasTextTarget::flush() { - for (int i = 0; i < fOps.count(); ++i) { - fOps[i].fOp->executeForTextTarget(this, fOps[i].fColor); - } - this->context()->internal().flush(); - fOps.reset(); -} - -void GrAtlasTextOp::executeForTextTarget(SkAtlasTextTarget* target, uint32_t color) { - FlushInfo flushInfo; - SkAutoGlyphCache glyphCache; - auto& context = target->context()->internal(); - auto* atlasGlyphCache = context.grContext()->getAtlasGlyphCache(); - for (int i = 0; i < fGeoCount; ++i) { - GrAtlasTextBlob::VertexRegenerator regenerator( - fGeoData[i].fBlob, fGeoData[i].fRun, fGeoData[i].fSubRun, fGeoData[i].fViewMatrix, - fGeoData[i].fX, fGeoData[i].fY, color, &context, atlasGlyphCache, &glyphCache); - GrAtlasTextBlob::VertexRegenerator::Result result; - do { - result = regenerator.regenerate(); - context.recordDraw(result.fFirstVertex, result.fGlyphsRegenerated, target->handle()); - if (!result.fFinished) { - // Make space in the atlas so we can continue generating vertices. - context.flush(); - } - } while (!result.fFinished); - } -} diff --git a/src/atlastext/SkInternalAtlasTextContext.cpp b/src/atlastext/SkInternalAtlasTextContext.cpp deleted file mode 100644 index 8be7e1fb67..0000000000 --- a/src/atlastext/SkInternalAtlasTextContext.cpp +++ /dev/null @@ -1,117 +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 "SkInternalAtlasTextContext.h" -#include "GrContext.h" -#include "SkAtlasTextContext.h" -#include "SkAtlasTextRenderer.h" -#include "text/GrAtlasGlyphCache.h" - -SkAtlasTextRenderer* SkGetAtlasTextRendererFromInternalContext( - class SkInternalAtlasTextContext& internal) { - return internal.renderer(); -} - -////////////////////////////////////////////////////////////////////////////// - -std::unique_ptr<SkInternalAtlasTextContext> SkInternalAtlasTextContext::Make( - sk_sp<SkAtlasTextRenderer> renderer) { - return std::unique_ptr<SkInternalAtlasTextContext>( - new SkInternalAtlasTextContext(std::move(renderer))); -} - -SkInternalAtlasTextContext::SkInternalAtlasTextContext(sk_sp<SkAtlasTextRenderer> renderer) - : fRenderer(std::move(renderer)) { - GrContextOptions options; - options.fAllowMultipleGlyphCacheTextures = GrContextOptions::Enable::kNo; - options.fMinDistanceFieldFontSize = 0.f; - options.fGlyphsAsPathsFontSize = SK_ScalarInfinity; - fGrContext = GrContext::MakeMock(nullptr, options); -} - -SkInternalAtlasTextContext::~SkInternalAtlasTextContext() { - if (fDistanceFieldAtlas.fProxy) { - SkASSERT(1 == fGrContext->getAtlasGlyphCache()->getAtlasPageCount(kA8_GrMaskFormat)); - fRenderer->deleteTexture(fDistanceFieldAtlas.fTextureHandle); - } -} - -GrAtlasGlyphCache* SkInternalAtlasTextContext::atlasGlyphCache() { - return fGrContext->getAtlasGlyphCache(); -} - -GrTextBlobCache* SkInternalAtlasTextContext::textBlobCache() { - return fGrContext->getTextBlobCache(); -} - -GrDeferredUploadToken SkInternalAtlasTextContext::addInlineUpload( - GrDeferredTextureUploadFn&& upload) { - auto token = this->nextDrawToken(); - fInlineUploads.append(&fArena, InlineUpload{std::move(upload), token}); - return token; -} - -GrDeferredUploadToken SkInternalAtlasTextContext::addASAPUpload( - GrDeferredTextureUploadFn&& upload) { - fASAPUploads.append(&fArena, std::move(upload)); - return this->nextTokenToFlush(); -} - -void SkInternalAtlasTextContext::recordDraw(const void* srcVertexData, int glyphCnt, - void* targetHandle) { - auto vertexDataSize = sizeof(SkAtlasTextRenderer::SDFVertex) * 4 * glyphCnt; - auto vertexData = fArena.makeArrayDefault<char>(vertexDataSize); - memcpy(vertexData, srcVertexData, vertexDataSize); - for (int i = 0; i < 4 * glyphCnt; ++i) { - auto* vertex = reinterpret_cast<SkAtlasTextRenderer::SDFVertex*>(vertexData) + i; - // GrAtlasTextContext encodes a texture index into the lower bit of each texture coord. - // This isn't expected by SkAtlasTextRenderer subclasses. - vertex->fTextureCoord.fX /= 2; - vertex->fTextureCoord.fY /= 2; - } - fDraws.append(&fArena, Draw{glyphCnt, this->issueDrawToken(), targetHandle, vertexData}); -} - -void SkInternalAtlasTextContext::flush() { - auto* atlasGlyphCache = fGrContext->getAtlasGlyphCache(); - if (!fDistanceFieldAtlas.fProxy) { - SkASSERT(1 == atlasGlyphCache->getAtlasPageCount(kA8_GrMaskFormat)); - fDistanceFieldAtlas.fProxy = atlasGlyphCache->getProxies(kA8_GrMaskFormat)->get(); - fDistanceFieldAtlas.fTextureHandle = - fRenderer->createTexture(SkAtlasTextRenderer::AtlasFormat::kA8, - fDistanceFieldAtlas.fProxy->width(), - fDistanceFieldAtlas.fProxy->height()); - } - GrDeferredTextureUploadWritePixelsFn writePixelsFn = - [this](GrTextureProxy* proxy, int left, int top, int width, int height, - GrPixelConfig config, const void* data, size_t rowBytes) -> bool { - SkASSERT(kAlpha_8_GrPixelConfig == config); - SkASSERT(proxy == this->fDistanceFieldAtlas.fProxy); - void* handle = fDistanceFieldAtlas.fTextureHandle; - this->fRenderer->setTextureData(handle, data, left, top, width, height, rowBytes); - return true; - }; - for (const auto& upload : fASAPUploads) { - upload(writePixelsFn); - } - auto draw = fDraws.begin(); - auto inlineUpload = fInlineUploads.begin(); - while (draw != fDraws.end()) { - while (inlineUpload != fInlineUploads.end() && inlineUpload->fToken == draw->fToken) { - inlineUpload->fUpload(writePixelsFn); - ++inlineUpload; - } - auto vertices = reinterpret_cast<const SkAtlasTextRenderer::SDFVertex*>(draw->fVertexData); - fRenderer->drawSDFGlyphs(draw->fTargetHandle, fDistanceFieldAtlas.fTextureHandle, vertices, - draw->fGlyphCnt); - ++draw; - } - fASAPUploads.reset(); - fInlineUploads.reset(); - fDraws.reset(); - fArena.reset(); -} diff --git a/src/atlastext/SkInternalAtlasTextContext.h b/src/atlastext/SkInternalAtlasTextContext.h deleted file mode 100644 index 1bb12cee5a..0000000000 --- a/src/atlastext/SkInternalAtlasTextContext.h +++ /dev/null @@ -1,80 +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 SkInternalAtlasTextContext_DEFINED -#define SkInternalAtlasTextContext_DEFINED - -#include "GrDeferredUpload.h" -#include "SkArenaAlloc.h" -#include "SkArenaAllocList.h" -#include "SkRefCnt.h" - -class SkAtlasTextRenderer; -class GrContext; -class GrAtlasGlyphCache; -class GrTextBlobCache; - -/** - * The implementation of SkAtlasTextContext. This exists to hide the details from the public class. - * and to be able to use other private types. - */ -class SkInternalAtlasTextContext : public GrDeferredUploadTarget { -public: - static std::unique_ptr<SkInternalAtlasTextContext> Make(sk_sp<SkAtlasTextRenderer>); - - ~SkInternalAtlasTextContext() override; - - SkAtlasTextRenderer* renderer() const { return fRenderer.get(); } - - GrContext* grContext() const { return fGrContext.get(); } - GrAtlasGlyphCache* atlasGlyphCache(); - GrTextBlobCache* textBlobCache(); - - GrDeferredUploadToken addInlineUpload(GrDeferredTextureUploadFn&&) override; - - GrDeferredUploadToken addASAPUpload(GrDeferredTextureUploadFn&&) override; - - void recordDraw(const void* vertexData, int glyphCnt, void* targetHandle); - - void flush(); - -private: - class DeferredUploader; - SkInternalAtlasTextContext() = delete; - SkInternalAtlasTextContext(const SkInternalAtlasTextContext&) = delete; - SkInternalAtlasTextContext& operator=(const SkInternalAtlasTextContext&) = delete; - - SkInternalAtlasTextContext(sk_sp<SkAtlasTextRenderer>); - - sk_sp<SkAtlasTextRenderer> fRenderer; - - struct AtlasTexture { - void* fTextureHandle = nullptr; - GrTextureProxy* fProxy = nullptr; - }; - - struct Draw { - int fGlyphCnt; - GrDeferredUploadToken fToken; - void* fTargetHandle; - const void* fVertexData; - }; - - struct InlineUpload { - GrDeferredTextureUploadFn fUpload; - GrDeferredUploadToken fToken; - }; - - SkArenaAllocList<InlineUpload> fInlineUploads; - SkArenaAllocList<Draw> fDraws; - SkArenaAllocList<GrDeferredTextureUploadFn> fASAPUploads; - SkArenaAlloc fArena{1024 * 40}; - sk_sp<GrContext> fGrContext; - AtlasTexture fDistanceFieldAtlas; -}; - -#endif diff --git a/src/core/SkArenaAlloc.h b/src/core/SkArenaAlloc.h index 2f23382ac1..9e971610a6 100644 --- a/src/core/SkArenaAlloc.h +++ b/src/core/SkArenaAlloc.h @@ -5,8 +5,8 @@ * found in the LICENSE file. */ -#ifndef SkArenaAlloc_DEFINED -#define SkArenaAlloc_DEFINED +#ifndef SkFixedAlloc_DEFINED +#define SkFixedAlloc_DEFINED #include "SkRefCnt.h" #include "SkTFitsIn.h" @@ -240,4 +240,4 @@ private: using INHERITED = SkArenaAlloc; }; -#endif // SkArenaAlloc_DEFINED +#endif//SkFixedAlloc_DEFINED diff --git a/src/core/SkArenaAllocList.h b/src/core/SkArenaAllocList.h deleted file mode 100644 index b4e442b0bd..0000000000 --- a/src/core/SkArenaAllocList.h +++ /dev/null @@ -1,79 +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 SkArenaAllocList_DEFINED -#define SkArenaAllocList_DEFINED - -#include "SkArenaAlloc.h" - -/** - * A singly linked list of Ts stored in a SkArenaAlloc. The arena rather than the list owns - * the elements. This supports forward iteration and range based for loops. - */ -template <typename T> -class SkArenaAllocList { -private: - struct Node; - -public: - SkArenaAllocList() = default; - - void reset() { fHead = fTail = nullptr; } - - template <typename... Args> - inline T& append(SkArenaAlloc* arena, Args... args); - - class Iter { - public: - Iter() = default; - inline Iter& operator++(); - T& operator*() const { return fCurr->fT; } - T* operator->() const { return &fCurr->fT; } - bool operator==(const Iter& that) const { return fCurr == that.fCurr; } - bool operator!=(const Iter& that) const { return !(*this == that); } - - private: - friend class SkArenaAllocList; - explicit Iter(Node* node) : fCurr(node) {} - Node* fCurr = nullptr; - }; - - Iter begin() { return Iter(fHead); } - Iter end() { return Iter(); } - Iter tail() { return Iter(fTail); } - -private: - struct Node { - template <typename... Args> - Node(Args... args) : fT(std::forward<Args>(args)...) {} - T fT; - Node* fNext = nullptr; - }; - Node* fHead = nullptr; - Node* fTail = nullptr; -}; - -template <typename T> -template <typename... Args> -T& SkArenaAllocList<T>::append(SkArenaAlloc* arena, Args... args) { - SkASSERT(!fHead == !fTail); - auto* n = arena->make<Node>(std::forward<Args>(args)...); - if (!fTail) { - fHead = fTail = n; - } else { - fTail = fTail->fNext = n; - } - return fTail->fT; -} - -template <typename T> -typename SkArenaAllocList<T>::Iter& SkArenaAllocList<T>::Iter::operator++() { - fCurr = fCurr->fNext; - return *this; -} - -#endif diff --git a/src/gpu/GrOpFlushState.cpp b/src/gpu/GrOpFlushState.cpp index 5245a9d9b2..6ac5d13430 100644 --- a/src/gpu/GrOpFlushState.cpp +++ b/src/gpu/GrOpFlushState.cpp @@ -12,6 +12,25 @@ #include "GrResourceProvider.h" #include "GrTexture.h" +template <typename T> +template <typename... Args> +T& GrOpFlushState::List<T>::append(SkArenaAlloc* arena, Args... args) { + SkASSERT(!fHead == !fTail); + auto* n = arena->make<Node>(std::forward<Args>(args)...); + if (!fTail) { + fHead = fTail = n; + } else { + fTail = fTail->fNext = n; + } + return fTail->fT; +} + +template <typename T> +typename GrOpFlushState::List<T>::Iter& GrOpFlushState::List<T>::Iter::operator++() { + fCurr = fCurr->fNext; + return *this; +} + ////////////////////////////////////////////////////////////////////////////// GrOpFlushState::GrOpFlushState(GrGpu* gpu, GrResourceProvider* resourceProvider) diff --git a/src/gpu/GrOpFlushState.h b/src/gpu/GrOpFlushState.h index a9cf9a070f..b20098aac7 100644 --- a/src/gpu/GrOpFlushState.h +++ b/src/gpu/GrOpFlushState.h @@ -13,7 +13,6 @@ #include "GrBufferAllocPool.h" #include "GrDeferredUpload.h" #include "SkArenaAlloc.h" -#include "SkArenaAllocList.h" #include "ops/GrMeshDrawOp.h" class GrGpu; @@ -111,6 +110,53 @@ private: uint32_t fOpID; }; + /** + * A singly linked list of Ts stored in a SkArenaAlloc. The arena rather than the list owns + * the elements. This supports forward iteration and range based for loops. + */ + template <typename T> + class List { + private: + struct Node; + + public: + List() = default; + + void reset() { fHead = fTail = nullptr; } + + template <typename... Args> + T& append(SkArenaAlloc* arena, Args... args); + + class Iter { + public: + Iter() = default; + Iter& operator++(); + T& operator*() const { return fCurr->fT; } + T* operator->() const { return &fCurr->fT; } + bool operator==(const Iter& that) const { return fCurr == that.fCurr; } + bool operator!=(const Iter& that) const { return !(*this == that); } + + private: + friend class List; + explicit Iter(Node* node) : fCurr(node) {} + Node* fCurr = nullptr; + }; + + Iter begin() { return Iter(fHead); } + Iter end() { return Iter(); } + Iter tail() { return Iter(fTail); } + + private: + struct Node { + template <typename... Args> + Node(Args... args) : fT(std::forward<Args>(args)...) {} + T fT; + Node* fNext = nullptr; + }; + Node* fHead = nullptr; + Node* fTail = nullptr; + }; + // Storage for ops' pipelines, draws, and inline uploads. SkArenaAlloc fArena{sizeof(GrPipeline) * 100}; @@ -119,9 +165,9 @@ private: GrIndexBufferAllocPool fIndexPool; // Data stored on behalf of the ops being flushed. - SkArenaAllocList<GrDeferredTextureUploadFn> fAsapUploads; - SkArenaAllocList<InlineUpload> fInlineUploads; - SkArenaAllocList<Draw> fDraws; + List<GrDeferredTextureUploadFn> fAsapUploads; + List<InlineUpload> fInlineUploads; + List<Draw> fDraws; // TODO: These should go in the arena. However, GrGpuCommandBuffer and other classes currently // accept contiguous arrays of meshes. SkSTArray<16, GrMesh> fMeshes; @@ -139,9 +185,9 @@ private: GrGpuCommandBuffer* fCommandBuffer = nullptr; // Variables that are used to track where we are in lists as ops are executed - SkArenaAllocList<Draw>::Iter fCurrDraw; + List<Draw>::Iter fCurrDraw; int fCurrMesh; - SkArenaAllocList<InlineUpload>::Iter fCurrUpload; + List<InlineUpload>::Iter fCurrUpload; }; #endif diff --git a/src/gpu/ops/GrAtlasTextOp.h b/src/gpu/ops/GrAtlasTextOp.h index c8ef643fd2..240b98b6f0 100644 --- a/src/gpu/ops/GrAtlasTextOp.h +++ b/src/gpu/ops/GrAtlasTextOp.h @@ -12,8 +12,6 @@ #include "text/GrAtlasTextContext.h" #include "text/GrDistanceFieldAdjustTable.h" -class SkAtlasTextTarget; - class GrAtlasTextOp final : public GrMeshDrawOp { public: DEFINE_OP_CLASS_ID @@ -118,20 +116,6 @@ public: RequiresDstTexture finalize(const GrCaps& caps, const GrAppliedClip* clip, GrPixelConfigIsClamped dstIsClamped) override; - enum MaskType { - kGrayscaleCoverageMask_MaskType, - kLCDCoverageMask_MaskType, - kColorBitmapMask_MaskType, - kAliasedDistanceField_MaskType, - kGrayscaleDistanceField_MaskType, - kLCDDistanceField_MaskType, - kLCDBGRDistanceField_MaskType, - }; - - MaskType maskType() const { return fMaskType; } - - void executeForTextTarget(SkAtlasTextTarget*, uint32_t color); - private: // The minimum number of Geometry we will try to allocate. static constexpr auto kMinGeometryAllocated = 12; @@ -196,6 +180,16 @@ private: sk_sp<GrGeometryProcessor> setupDfProcessor() const; + enum MaskType { + kGrayscaleCoverageMask_MaskType, + kLCDCoverageMask_MaskType, + kColorBitmapMask_MaskType, + kAliasedDistanceField_MaskType, + kGrayscaleDistanceField_MaskType, + kLCDDistanceField_MaskType, + kLCDBGRDistanceField_MaskType, + }; + SkAutoSTMalloc<kMinGeometryAllocated, Geometry> fGeoData; int fGeoDataAllocSize; GrColor fColor; diff --git a/tools/gpu/atlastext/GLTestAtlasTextRenderer.cpp b/tools/gpu/atlastext/GLTestAtlasTextRenderer.cpp deleted file mode 100644 index 543f46012b..0000000000 --- a/tools/gpu/atlastext/GLTestAtlasTextRenderer.cpp +++ /dev/null @@ -1,439 +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 "GLTestAtlasTextRenderer.h" -#include "../gl/GLTestContext.h" -#include "SkBitmap.h" -#include "TestAtlasTextRenderer.h" -#include "gl/GrGLDefines.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* target) override; - - SkBitmap readTargetHandle(void* target) 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(); - 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 vec2 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, 1.0); - } - )"; - 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, 2, GR_GL_FLOAT, GR_GL_FALSE, sizeof(SDFVertex), vertices); - size_t colorOffset = 2 * 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.5, 0.5, 0.5, 1.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* target) { - auto restore = fContext->makeCurrentAndAutoRestore(); - - Target* t = reinterpret_cast<Target*>(target); - callgl(DeleteFramebuffers, 1, &t->fFBOID); - callgl(DeleteRenderbuffers, 1, &t->fRBID); - delete t; -} - -SkBitmap GLTestAtlasTextRenderer::readTargetHandle(void* target) { - auto restore = fContext->makeCurrentAndAutoRestore(); - - Target* t = reinterpret_cast<Target*>(target); - - auto info = - SkImageInfo::Make(t->fWidth, t->fHeight, kRGBA_8888_SkColorType, kPremul_SkAlphaType); - SkBitmap bmp; - bmp.setInfo(info, sizeof(uint32_t) * t->fWidth); - bmp.allocPixels(); - - callgl(BindFramebuffer, GR_GL_FRAMEBUFFER, t->fFBOID); - callgl(ReadPixels, 0, 0, t->fWidth, t->fHeight, GR_GL_RGBA, GR_GL_UNSIGNED_BYTE, - bmp.getPixels()); - checkgl(); - return bmp; -} - -} // 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/tools/gpu/atlastext/GLTestAtlasTextRenderer.h b/tools/gpu/atlastext/GLTestAtlasTextRenderer.h deleted file mode 100644 index df01b345de..0000000000 --- a/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 "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/tools/gpu/atlastext/TestAtlasTextRenderer.h b/tools/gpu/atlastext/TestAtlasTextRenderer.h deleted file mode 100644 index 068a60d2bb..0000000000 --- a/tools/gpu/atlastext/TestAtlasTextRenderer.h +++ /dev/null @@ -1,34 +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 "SkAtlasTextRenderer.h" -#include "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; -}; - -} // namespace sk_gpu_test - -#endif diff --git a/tools/gpu/gl/glx/CreatePlatformGLTestContext_glx.cpp b/tools/gpu/gl/glx/CreatePlatformGLTestContext_glx.cpp index 066784df69..a6b2637c4b 100644 --- a/tools/gpu/gl/glx/CreatePlatformGLTestContext_glx.cpp +++ b/tools/gpu/gl/glx/CreatePlatformGLTestContext_glx.cpp @@ -107,11 +107,6 @@ GLXGLTestContext::GLXGLTestContext(GrGLStandard forcedGpuAPI, GLXGLTestContext* , fDisplay(nullptr) , fPixmap(0) , fGlxPixmap(0) { - // We cross our fingers that this is the first X call in the program and that if the application - // is actually threaded that this succeeds. - static SkOnce gOnce; - gOnce([] { XInitThreads(); }); - fDisplay = get_display(); GLXContext glxShareContext = shareContext ? shareContext->fContext : nullptr; |