OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "gl/GrGLPathRendering.h" | 8 #include "gl/GrGLPathRendering.h" |
9 #include "gl/GrGLNameAllocator.h" | 9 #include "gl/GrGLNameAllocator.h" |
10 #include "gl/GrGLUtil.h" | 10 #include "gl/GrGLUtil.h" |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 GrGLPathRendering::GrGLPathRendering(GrGLGpu* gpu) | 62 GrGLPathRendering::GrGLPathRendering(GrGLGpu* gpu) |
63 : GrPathRendering(gpu) { | 63 : GrPathRendering(gpu) { |
64 const GrGLInterface* glInterface = gpu->glInterface(); | 64 const GrGLInterface* glInterface = gpu->glInterface(); |
65 fCaps.stencilThenCoverSupport = | 65 fCaps.stencilThenCoverSupport = |
66 NULL != glInterface->fFunctions.fStencilThenCoverFillPath && | 66 NULL != glInterface->fFunctions.fStencilThenCoverFillPath && |
67 NULL != glInterface->fFunctions.fStencilThenCoverStrokePath && | 67 NULL != glInterface->fFunctions.fStencilThenCoverStrokePath && |
68 NULL != glInterface->fFunctions.fStencilThenCoverFillPathInstanced && | 68 NULL != glInterface->fFunctions.fStencilThenCoverFillPathInstanced && |
69 NULL != glInterface->fFunctions.fStencilThenCoverStrokePathInstanced; | 69 NULL != glInterface->fFunctions.fStencilThenCoverStrokePathInstanced; |
70 fCaps.fragmentInputGenSupport = | 70 fCaps.fragmentInputGenSupport = |
71 NULL != glInterface->fFunctions.fProgramPathFragmentInputGen; | 71 NULL != glInterface->fFunctions.fProgramPathFragmentInputGen; |
72 fCaps.glyphLoadingSupport = | |
73 NULL != glInterface->fFunctions.fPathMemoryGlyphIndexArray; | |
74 | 72 |
75 SkASSERT(fCaps.fragmentInputGenSupport); | 73 SkASSERT(fCaps.fragmentInputGenSupport); |
76 } | 74 } |
77 | 75 |
78 GrGLPathRendering::~GrGLPathRendering() { | 76 GrGLPathRendering::~GrGLPathRendering() { |
79 } | 77 } |
80 | 78 |
81 void GrGLPathRendering::abandonGpuResources() { | 79 void GrGLPathRendering::abandonGpuResources() { |
82 fPathNameAllocator.reset(NULL); | 80 fPathNameAllocator.reset(NULL); |
83 } | 81 } |
84 | 82 |
85 void GrGLPathRendering::resetContext() { | 83 void GrGLPathRendering::resetContext() { |
86 fHWProjectionMatrixState.invalidate(); | 84 fHWProjectionMatrixState.invalidate(); |
87 // we don't use the model view matrix. | 85 // we don't use the model view matrix. |
88 GL_CALL(MatrixLoadIdentity(GR_GL_PATH_MODELVIEW)); | 86 GL_CALL(MatrixLoadIdentity(GR_GL_PATH_MODELVIEW)); |
89 | 87 |
90 SkASSERT(fCaps.fragmentInputGenSupport); | 88 SkASSERT(fCaps.fragmentInputGenSupport); |
91 fHWPathStencilSettings.invalidate(); | 89 fHWPathStencilSettings.invalidate(); |
92 } | 90 } |
93 | 91 |
94 GrPath* GrGLPathRendering::createPath(const SkPath& inPath, const GrStrokeInfo&
stroke) { | 92 GrPath* GrGLPathRendering::createPath(const SkPath& inPath, const GrStrokeInfo&
stroke) { |
95 return SkNEW_ARGS(GrGLPath, (this->gpu(), inPath, stroke)); | 93 return SkNEW_ARGS(GrGLPath, (this->gpu(), inPath, stroke)); |
96 } | 94 } |
97 | 95 |
98 GrPathRange* GrGLPathRendering::createPathRange(GrPathRange::PathGenerator* path
Generator, | 96 GrPathRange* GrGLPathRendering::createPathRange(GrPathRange::PathGenerator* path
Generator, |
99 const GrStrokeInfo& stroke) { | 97 const GrStrokeInfo& stroke) { |
100 return SkNEW_ARGS(GrGLPathRange, (this->gpu(), pathGenerator, stroke)); | 98 return SkNEW_ARGS(GrGLPathRange, (this->gpu(), pathGenerator, stroke)); |
101 } | 99 } |
102 | 100 |
103 GrPathRange* GrGLPathRendering::createGlyphs(const SkTypeface* typeface, | |
104 const SkDescriptor* desc, | |
105 const GrStrokeInfo& stroke) { | |
106 if (NULL != desc || !caps().glyphLoadingSupport || stroke.isDashed()) { | |
107 return GrPathRendering::createGlyphs(typeface, desc, stroke); | |
108 } | |
109 | |
110 if (NULL == typeface) { | |
111 typeface = SkTypeface::GetDefaultTypeface(); | |
112 SkASSERT(NULL != typeface); | |
113 } | |
114 | |
115 int faceIndex; | |
116 SkStreamAsset* asset = typeface->openStream(&faceIndex); | |
117 if (!asset) { | |
118 return GrPathRendering::createGlyphs(typeface, NULL, stroke); | |
119 } | |
120 SkAutoTDelete<SkStream> fontStream(asset); | |
121 | |
122 const size_t fontDataLength = fontStream->getLength(); | |
123 if (0 == fontDataLength) { | |
124 return GrPathRendering::createGlyphs(typeface, NULL, stroke); | |
125 } | |
126 | |
127 SkTArray<uint8_t> fontTempBuffer; | |
128 const void* fontData = fontStream->getMemoryBase(); | |
129 if (NULL == fontData) { | |
130 // TODO: Find a more efficient way to pass the font data (e.g. open file
descriptor). | |
131 fontTempBuffer.reset(SkToInt(fontDataLength)); | |
132 fontStream->read(&fontTempBuffer.front(), fontDataLength); | |
133 fontData = &fontTempBuffer.front(); | |
134 } | |
135 | |
136 const int numPaths = typeface->countGlyphs(); | |
137 const GrGLuint basePathID = this->genPaths(numPaths); | |
138 | |
139 // Init the basePathID as the template path. | |
140 GrGLPath::InitPathObject(this->gpu(), basePathID, SkPath(), stroke); | |
141 | |
142 GrGLenum status; | |
143 GL_CALL_RET(status, PathMemoryGlyphIndexArray(basePathID, GR_GL_STANDARD_FON
T_FORMAT, | |
144 fontDataLength, fontData, face
Index, 0, | |
145 numPaths, basePathID, | |
146 SkPaint::kCanonicalTextSizeFor
Paths)); | |
147 | |
148 if (GR_GL_FONT_GLYPHS_AVAILABLE != status) { | |
149 this->deletePaths(basePathID, numPaths); | |
150 return GrPathRendering::createGlyphs(typeface, NULL, stroke); | |
151 } | |
152 | |
153 // This is a crude approximation. We may want to consider giving this class | |
154 // a pseudo PathGenerator whose sole purpose is to track the approximate gpu | |
155 // memory size. | |
156 const size_t gpuMemorySize = fontDataLength / 4; | |
157 return SkNEW_ARGS(GrGLPathRange, (this->gpu(), basePathID, numPaths, gpuMemo
rySize, stroke)); | |
158 } | |
159 | |
160 void GrGLPathRendering::onStencilPath(const StencilPathArgs& args, const GrPath*
path) { | 101 void GrGLPathRendering::onStencilPath(const StencilPathArgs& args, const GrPath*
path) { |
161 GrGLGpu* gpu = this->gpu(); | 102 GrGLGpu* gpu = this->gpu(); |
162 SkASSERT(gpu->caps()->shaderCaps()->pathRenderingSupport()); | 103 SkASSERT(gpu->caps()->shaderCaps()->pathRenderingSupport()); |
163 gpu->flushColorWrite(false); | 104 gpu->flushColorWrite(false); |
164 gpu->flushDrawFace(GrPipelineBuilder::kBoth_DrawFace); | 105 gpu->flushDrawFace(GrPipelineBuilder::kBoth_DrawFace); |
165 | 106 |
166 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(args.fRenderTarget); | 107 GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(args.fRenderTarget); |
167 SkISize size = SkISize::Make(rt->width(), rt->height()); | 108 SkISize size = SkISize::Make(rt->width(), rt->height()); |
168 this->setProjectionMatrix(*args.fViewMatrix, size, rt->origin()); | 109 this->setProjectionMatrix(*args.fViewMatrix, size, rt->origin()); |
169 gpu->flushScissor(*args.fScissor, rt->getViewport(), rt->origin()); | 110 gpu->flushScissor(*args.fScissor, rt->getViewport(), rt->origin()); |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
407 | 348 |
408 GL_CALL(StencilStrokePathInstanced(numPaths, pathNameType, paths, pathBase, | 349 GL_CALL(StencilStrokePathInstanced(numPaths, pathNameType, paths, pathBase, |
409 reference, mask, transformType, transform
Values)); | 350 reference, mask, transformType, transform
Values)); |
410 GL_CALL(CoverStrokePathInstanced(numPaths, pathNameType, paths, pathBase, | 351 GL_CALL(CoverStrokePathInstanced(numPaths, pathNameType, paths, pathBase, |
411 coverMode, transformType, transformValues))
; | 352 coverMode, transformType, transformValues))
; |
412 } | 353 } |
413 | 354 |
414 inline GrGLGpu* GrGLPathRendering::gpu() { | 355 inline GrGLGpu* GrGLPathRendering::gpu() { |
415 return static_cast<GrGLGpu*>(fGpu); | 356 return static_cast<GrGLGpu*>(fGpu); |
416 } | 357 } |
OLD | NEW |