diff options
-rw-r--r-- | gn/samples.gni | 1 | ||||
-rw-r--r-- | samplecode/SampleFlutterAnimate.cpp | 107 | ||||
-rw-r--r-- | src/gpu/GrContext.cpp | 20 | ||||
-rw-r--r-- | src/gpu/effects/GrAtlasedShaderHelpers.h | 20 | ||||
-rw-r--r-- | src/gpu/effects/GrBitmapTextGeoProc.cpp | 3 | ||||
-rw-r--r-- | src/gpu/effects/GrDistanceFieldGeoProc.cpp | 9 | ||||
-rw-r--r-- | src/gpu/text/GrAtlasTextBlobVertexRegenerator.cpp | 38 |
7 files changed, 174 insertions, 24 deletions
diff --git a/gn/samples.gni b/gn/samples.gni index 6e1bcac893..7c0d9e2617 100644 --- a/gn/samples.gni +++ b/gn/samples.gni @@ -48,6 +48,7 @@ samples_sources = [ "$_samplecode/SampleFilter2.cpp", "$_samplecode/SampleFilterFuzz.cpp", "$_samplecode/SampleFilterQuality.cpp", + "$_samplecode/SampleFlutterAnimate.cpp", "$_samplecode/SampleFontScalerTest.cpp", "$_samplecode/SampleFuzz.cpp", "$_samplecode/SampleGradients.cpp", diff --git a/samplecode/SampleFlutterAnimate.cpp b/samplecode/SampleFlutterAnimate.cpp new file mode 100644 index 0000000000..63b453b240 --- /dev/null +++ b/samplecode/SampleFlutterAnimate.cpp @@ -0,0 +1,107 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SampleCode.h" +#include "SkAnimTimer.h" +#include "SkView.h" +#include "SkCanvas.h" +#include "SkUtils.h" +#include "SkColorPriv.h" +#include "SkColorFilter.h" +#include "SkImage.h" +#include "SkRandom.h" +#include "SkSystemEventTypes.h" +#include "SkTime.h" +#include "SkTypeface.h" +#include "Timer.h" + +#if SK_SUPPORT_GPU +#include "GrContext.h" +#endif + +class FlutterAnimateView : public SampleView { +public: + FlutterAnimateView() : fCurrTime(0), fResetTime(0) {} + +protected: + void onOnceBeforeDraw() override { + initChars(); + } + + // overrides from SkEventSink + bool onQuery(SkEvent* evt) override { + if (SampleCode::TitleQ(*evt)) { + SampleCode::TitleR(evt, "FlutterAnimate"); + return true; + } + + return this->INHERITED::onQuery(evt); + } + + void onDrawContent(SkCanvas* canvas) override { + SkPaint paint; + paint.setTypeface(SkTypeface::MakeFromFile("/skimages/samplefont.ttf")); + paint.setAntiAlias(true); + paint.setFilterQuality(kMedium_SkFilterQuality); + paint.setTextSize(50); + + canvas->clear(SK_ColorWHITE); + for (int i = 0; i < kNumChars; ++i) { + canvas->save(); + double rot = fChars[i].fStartRotation + (fChars[i].fEndRotation - fChars[i].fStartRotation)*fCurrTime/kDuration; + canvas->translate(fChars[i].fPosition.fX + 35,fChars[i].fPosition.fY - 50); + canvas->rotate(rot*180.0/SK_MScalarPI); + canvas->translate(-35,+50); + canvas->drawString(fChars[i].fChar, 0, 0, + paint); + canvas->restore(); + } + } + + bool onAnimate(const SkAnimTimer& timer) override { + fCurrTime = timer.secs() - fResetTime; + if (fCurrTime > kDuration) { + this->initChars(); + fResetTime = timer.secs(); + fCurrTime = 0; + } + + return true; + } + +private: + void initChars() { + for (int i = 0; i < kNumChars; ++i) { + char c = fRand.nextULessThan(26) + 65; + fChars[i].fChar.set(&c, 1); + fChars[i].fPosition = SkPoint::Make(fRand.nextF()*748 + 10, fRand.nextF()*1004 + 10); + fChars[i].fStartRotation = fRand.nextF(); + fChars[i].fEndRotation = fRand.nextF() * 20 - 10; + } + } + + static constexpr double kDuration = 5.0; + double fCurrTime; + double fResetTime; + SkRandom fRand; + + struct AnimatedChar { + SkString fChar; + SkPoint fPosition; + SkScalar fStartRotation; + SkScalar fEndRotation; + }; + static constexpr int kNumChars = 40; + AnimatedChar fChars[kNumChars]; + + typedef SampleView INHERITED; +}; + +////////////////////////////////////////////////////////////////////////////// + +static SkView* MyFactory() { return new FlutterAnimateView; } +static SkViewRegister reg(MyFactory); diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 68cf42ef2a..69acd15cb2 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -211,20 +211,12 @@ bool GrContext::init(const GrContextOptions& options) { new GrDrawingManager(this, prcOptions, atlasTextContextOptions, &fSingleOwner)); GrDrawOpAtlas::AllowMultitexturing allowMultitexturing; - switch (options.fAllowMultipleGlyphCacheTextures) { - case GrContextOptions::Enable::kDefault: -#ifdef SK_BUILD_FOR_IOS - allowMultitexturing = GrDrawOpAtlas::AllowMultitexturing::kNo; -#else - allowMultitexturing = GrDrawOpAtlas::AllowMultitexturing::kYes; -#endif - break; - case GrContextOptions::Enable::kNo: - allowMultitexturing = GrDrawOpAtlas::AllowMultitexturing::kNo; - break; - case GrContextOptions::Enable::kYes: - allowMultitexturing = GrDrawOpAtlas::AllowMultitexturing::kYes; - break; + if (GrContextOptions::Enable::kNo == options.fAllowMultipleGlyphCacheTextures || + // multitexturing supported only if range can represent the index + texcoords fully + !(fCaps->shaderCaps()->floatIs32Bits() || fCaps->shaderCaps()->integerSupport())) { + allowMultitexturing = GrDrawOpAtlas::AllowMultitexturing::kNo; + } else { + allowMultitexturing = GrDrawOpAtlas::AllowMultitexturing::kYes; } fAtlasGlyphCache = new GrAtlasGlyphCache(this, options.fGlyphCacheTextureMaximumBytes, allowMultitexturing); diff --git a/src/gpu/effects/GrAtlasedShaderHelpers.h b/src/gpu/effects/GrAtlasedShaderHelpers.h index ad901411db..7fc321daa2 100644 --- a/src/gpu/effects/GrAtlasedShaderHelpers.h +++ b/src/gpu/effects/GrAtlasedShaderHelpers.h @@ -8,6 +8,7 @@ #ifndef GrAtlasedShaderHelpers_DEFINED #define GrAtlasedShaderHelpers_DEFINED +#include "GrShaderCaps.h" #include "glsl/GrGLSLPrimitiveProcessor.h" #include "glsl/GrGLSLFragmentShaderBuilder.h" #include "glsl/GrGLSLVarying.h" @@ -22,17 +23,24 @@ static void append_index_uv_varyings(GrGLSLPrimitiveProcessor::EmitArgs& args, // This extracts the texture index and texel coordinates from the same variable // Packing structure: texel coordinates are multiplied by 2 (or shifted left 1) // texture index is stored as lower bits of both x and y - args.fVertBuilder->codeAppendf("half2 indexTexCoords = half2(%s.x, %s.y);", - inTexCoordsName, inTexCoordsName); - args.fVertBuilder->codeAppend("half2 intCoords = floor(0.5*indexTexCoords);"); - args.fVertBuilder->codeAppend("half2 diff = indexTexCoords - 2.0*intCoords;"); - args.fVertBuilder->codeAppend("half texIdx = 2.0*diff.x + diff.y;"); + if (args.fShaderCaps->integerSupport()) { + args.fVertBuilder->codeAppendf("int2 signedCoords = int2(%s);", inTexCoordsName); + args.fVertBuilder->codeAppend("int texIdx = 2*(signedCoords.x & 0x1) + (signedCoords.y & 0x1);"); + args.fVertBuilder->codeAppend("signedCoords >>= 1;"); + args.fVertBuilder->codeAppend("float2 intCoords = float2(signedCoords);"); + } else { + args.fVertBuilder->codeAppendf("float2 indexTexCoords = float2(%s.x, %s.y);", + inTexCoordsName, inTexCoordsName); + args.fVertBuilder->codeAppend("float2 intCoords = floor(0.5*indexTexCoords);"); + args.fVertBuilder->codeAppend("float2 diff = indexTexCoords - 2.0*intCoords;"); + args.fVertBuilder->codeAppend("float texIdx = 2.0*diff.x + diff.y;"); + } // Multiply by 1/atlasSize to get normalized texture coordinates args.fVaryingHandler->addVarying("TextureCoords", uv); args.fVertBuilder->codeAppendf("%s = intCoords * %s;", uv->vsOut(), atlasSizeInvName); - args.fVaryingHandler->addVarying("TexIndex", texIdx); + args.fVaryingHandler->addFlatVarying("TexIndex", texIdx); args.fVertBuilder->codeAppendf("%s = texIdx;", texIdx->vsOut()); if (st) { diff --git a/src/gpu/effects/GrBitmapTextGeoProc.cpp b/src/gpu/effects/GrBitmapTextGeoProc.cpp index d5f930fec4..4193f1d24c 100644 --- a/src/gpu/effects/GrBitmapTextGeoProc.cpp +++ b/src/gpu/effects/GrBitmapTextGeoProc.cpp @@ -38,7 +38,8 @@ public: &atlasSizeInvName); GrGLSLVertToFrag uv(kFloat2_GrSLType); - GrGLSLVertToFrag texIdx(kHalf_GrSLType); + GrSLType texIdxType = args.fShaderCaps->integerSupport() ? kInt_GrSLType : kFloat_GrSLType; + GrGLSLVertToFrag texIdx(texIdxType); append_index_uv_varyings(args, btgp.inTextureCoords()->fName, atlasSizeInvName, &uv, &texIdx, nullptr); diff --git a/src/gpu/effects/GrDistanceFieldGeoProc.cpp b/src/gpu/effects/GrDistanceFieldGeoProc.cpp index aafabdeb60..3e9addef6d 100644 --- a/src/gpu/effects/GrDistanceFieldGeoProc.cpp +++ b/src/gpu/effects/GrDistanceFieldGeoProc.cpp @@ -78,7 +78,8 @@ public: // add varyings GrGLSLVertToFrag uv(kFloat2_GrSLType); - GrGLSLVertToFrag texIdx(kHalf_GrSLType); + GrSLType texIdxType = args.fShaderCaps->integerSupport() ? kInt_GrSLType : kFloat_GrSLType; + GrGLSLVertToFrag texIdx(texIdxType); GrGLSLVertToFrag st(kFloat2_GrSLType); append_index_uv_varyings(args, dfTexEffect.inTextureCoords()->fName, atlasSizeInvName, &uv, &texIdx, &st); @@ -344,7 +345,8 @@ public: &atlasSizeInvName); GrGLSLVertToFrag uv(kFloat2_GrSLType); - GrGLSLVertToFrag texIdx(kHalf_GrSLType); + GrSLType texIdxType = args.fShaderCaps->integerSupport() ? kInt_GrSLType : kFloat_GrSLType; + GrGLSLVertToFrag texIdx(texIdxType); GrGLSLVertToFrag st(kFloat2_GrSLType); append_index_uv_varyings(args, dfTexEffect.inTextureCoords()->fName, atlasSizeInvName, &uv, &texIdx, &st); @@ -639,7 +641,8 @@ public: // set up varyings GrGLSLVertToFrag uv(kFloat2_GrSLType); - GrGLSLVertToFrag texIdx(kHalf_GrSLType); + GrSLType texIdxType = args.fShaderCaps->integerSupport() ? kInt_GrSLType : kFloat_GrSLType; + GrGLSLVertToFrag texIdx(texIdxType); GrGLSLVertToFrag st(kFloat2_GrSLType); append_index_uv_varyings(args, dfTexEffect.inTextureCoords()->fName, atlasSizeInvName, &uv, &texIdx, &st); diff --git a/src/gpu/text/GrAtlasTextBlobVertexRegenerator.cpp b/src/gpu/text/GrAtlasTextBlobVertexRegenerator.cpp index 28b2e0f0c0..81ae09a6f5 100644 --- a/src/gpu/text/GrAtlasTextBlobVertexRegenerator.cpp +++ b/src/gpu/text/GrAtlasTextBlobVertexRegenerator.cpp @@ -38,6 +38,9 @@ inline void regen_vertices(char* vertex, const GrGlyph* glyph, size_t vertexStri bool useDistanceFields, SkScalar transX, SkScalar transY, GrColor color) { uint16_t u0, v0, u1, v1; +#ifdef DISPLAY_PAGE_INDEX + SkColor hackColor; +#endif if (regenTexCoords) { SkASSERT(glyph); int width = glyph->fBounds.width(); @@ -67,6 +70,25 @@ inline void regen_vertices(char* vertex, const GrGlyph* glyph, size_t vertexStri u1 |= uBit; v1 <<= 1; v1 |= vBit; +#ifdef DISPLAY_PAGE_INDEX + switch (pageIndex) { + case 0: + hackColor = SK_ColorGREEN; + break; + case 1: + hackColor = SK_ColorRED; + break; + case 2: + hackColor = SK_ColorMAGENTA; + break; + case 3: + hackColor = SK_ColorCYAN; + break; + default: + hackColor = SK_ColorBLACK; + break; + } +#endif } // This is a bit wonky, but sometimes we have LCD text, in which case we won't have color @@ -90,6 +112,10 @@ inline void regen_vertices(char* vertex, const GrGlyph* glyph, size_t vertexStri uint16_t* textureCoords = reinterpret_cast<uint16_t*>(vertex + texCoordOffset); textureCoords[0] = u0; textureCoords[1] = v0; +#ifdef DISPLAY_PAGE_INDEX + SkColor* vcolor = reinterpret_cast<SkColor*>(vertex + colorOffset); + *vcolor = hackColor; +#endif } vertex += vertexStride; @@ -109,6 +135,10 @@ inline void regen_vertices(char* vertex, const GrGlyph* glyph, size_t vertexStri uint16_t* textureCoords = reinterpret_cast<uint16_t*>(vertex + texCoordOffset); textureCoords[0] = u0; textureCoords[1] = v1; +#ifdef DISPLAY_PAGE_INDEX + SkColor* vcolor = reinterpret_cast<SkColor*>(vertex + colorOffset); + *vcolor = hackColor; +#endif } vertex += vertexStride; @@ -128,6 +158,10 @@ inline void regen_vertices(char* vertex, const GrGlyph* glyph, size_t vertexStri uint16_t* textureCoords = reinterpret_cast<uint16_t*>(vertex + texCoordOffset); textureCoords[0] = u1; textureCoords[1] = v0; +#ifdef DISPLAY_PAGE_INDEX + SkColor* vcolor = reinterpret_cast<SkColor*>(vertex + colorOffset); + *vcolor = hackColor; +#endif } vertex += vertexStride; @@ -147,6 +181,10 @@ inline void regen_vertices(char* vertex, const GrGlyph* glyph, size_t vertexStri uint16_t* textureCoords = reinterpret_cast<uint16_t*>(vertex + texCoordOffset); textureCoords[0] = u1; textureCoords[1] = v1; +#ifdef DISPLAY_PAGE_INDEX + SkColor* vcolor = reinterpret_cast<SkColor*>(vertex + colorOffset); + *vcolor = hackColor; +#endif } } |