@@ -1248,6 +1248,15 @@ bool OpenGLRenderer::quickRejectNoScissor(float left, float top, float right, fl
12481248 return !clip.intersects (transformed);
12491249}
12501250
1251+ bool OpenGLRenderer::quickRejectPreStroke (float left, float top, float right, float bottom, SkPaint* paint) {
1252+ if (paint->getStyle () != SkPaint::kFill_Style ) {
1253+ float outset = paint->getStrokeWidth () * 0 .5f ;
1254+ return quickReject (left - outset, top - outset, right + outset, bottom + outset);
1255+ } else {
1256+ return quickReject (left, top, right, bottom);
1257+ }
1258+ }
1259+
12511260bool OpenGLRenderer::quickReject (float left, float top, float right, float bottom) {
12521261 if (mSnapshot ->isIgnored ()) {
12531262 return true ;
@@ -1490,7 +1499,7 @@ void OpenGLRenderer::setupDrawTextGammaUniforms() {
14901499
14911500void OpenGLRenderer::setupDrawSimpleMesh () {
14921501 bool force = mCaches .bindMeshBuffer ();
1493- mCaches .bindPositionVertexPointer (force, mCaches . currentProgram -> position , 0 );
1502+ mCaches .bindPositionVertexPointer (force, 0 );
14941503 mCaches .unbindIndicesBuffer ();
14951504}
14961505
@@ -1523,26 +1532,25 @@ void OpenGLRenderer::setupDrawMesh(GLvoid* vertices, GLvoid* texCoords, GLuint v
15231532 force = mCaches .unbindMeshBuffer ();
15241533 }
15251534
1526- mCaches .bindPositionVertexPointer (force, mCaches . currentProgram -> position , vertices);
1535+ mCaches .bindPositionVertexPointer (force, vertices);
15271536 if (mCaches .currentProgram ->texCoords >= 0 ) {
1528- mCaches .bindTexCoordsVertexPointer (force, mCaches . currentProgram -> texCoords , texCoords);
1537+ mCaches .bindTexCoordsVertexPointer (force, texCoords);
15291538 }
15301539
15311540 mCaches .unbindIndicesBuffer ();
15321541}
15331542
15341543void OpenGLRenderer::setupDrawMeshIndices (GLvoid* vertices, GLvoid* texCoords) {
15351544 bool force = mCaches .unbindMeshBuffer ();
1536- mCaches .bindPositionVertexPointer (force, mCaches . currentProgram -> position , vertices);
1545+ mCaches .bindPositionVertexPointer (force, vertices);
15371546 if (mCaches .currentProgram ->texCoords >= 0 ) {
1538- mCaches .bindTexCoordsVertexPointer (force, mCaches . currentProgram -> texCoords , texCoords);
1547+ mCaches .bindTexCoordsVertexPointer (force, texCoords);
15391548 }
15401549}
15411550
15421551void OpenGLRenderer::setupDrawVertices (GLvoid* vertices) {
15431552 bool force = mCaches .unbindMeshBuffer ();
1544- mCaches .bindPositionVertexPointer (force, mCaches .currentProgram ->position ,
1545- vertices, gVertexStride );
1553+ mCaches .bindPositionVertexPointer (force, vertices, gVertexStride );
15461554 mCaches .unbindIndicesBuffer ();
15471555}
15481556
@@ -1560,8 +1568,7 @@ void OpenGLRenderer::setupDrawVertices(GLvoid* vertices) {
15601568void OpenGLRenderer::setupDrawAALine (GLvoid* vertices, GLvoid* widthCoords,
15611569 GLvoid* lengthCoords, float boundaryWidthProportion, int & widthSlot, int & lengthSlot) {
15621570 bool force = mCaches .unbindMeshBuffer ();
1563- mCaches .bindPositionVertexPointer (force, mCaches .currentProgram ->position ,
1564- vertices, gAAVertexStride );
1571+ mCaches .bindPositionVertexPointer (force, vertices, gAAVertexStride );
15651572 mCaches .resetTexCoordsVertexPointer ();
15661573 mCaches .unbindIndicesBuffer ();
15671574
@@ -1919,15 +1926,23 @@ status_t OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const
19191926}
19201927
19211928/* *
1922- * This function uses a similar approach to that of AA lines in the drawLines() function.
1923- * We expand the rectangle by a half pixel in screen space on all sides. However, instead of using
1924- * a fragment shader to compute the translucency of the color from its position, we simply use a
1925- * varying parameter to define how far a given pixel is into the region.
1929+ * Renders a convex path via tessellation. For AA paths, this function uses a similar approach to
1930+ * that of AA lines in the drawLines() function. We expand the convex path by a half pixel in
1931+ * screen space in all directions. However, instead of using a fragment shader to compute the
1932+ * translucency of the color from its position, we simply use a varying parameter to define how far
1933+ * a given pixel is from the edge. For non-AA paths, the expansion and alpha varying are not used.
1934+ *
1935+ * Doesn't yet support joins, caps, or path effects.
19261936 */
1927- void OpenGLRenderer::drawConvexPath (const SkPath& path, int color, SkXfermode::Mode mode, bool isAA) {
1937+ void OpenGLRenderer::drawConvexPath (const SkPath& path, SkPaint* paint) {
1938+ int color = paint->getColor ();
1939+ SkPaint::Style style = paint->getStyle ();
1940+ SkXfermode::Mode mode = getXfermode (paint->getXfermode ());
1941+ bool isAA = paint->isAntiAlias ();
1942+
19281943 VertexBuffer vertexBuffer;
19291944 // TODO: try clipping large paths to viewport
1930- PathRenderer::convexPathFillVertices (path, mSnapshot ->transform , vertexBuffer, isAA );
1945+ PathRenderer::convexPathVertices (path, paint, mSnapshot ->transform , vertexBuffer);
19311946
19321947 setupDraw ();
19331948 setupDrawNoTexture ();
@@ -1938,15 +1953,14 @@ void OpenGLRenderer::drawConvexPath(const SkPath& path, int color, SkXfermode::M
19381953 setupDrawShader ();
19391954 setupDrawBlending (isAA, mode);
19401955 setupDrawProgram ();
1941- setupDrawModelViewIdentity (true );
1956+ setupDrawModelViewIdentity ();
19421957 setupDrawColorUniforms ();
19431958 setupDrawColorFilterUniforms ();
19441959 setupDrawShaderIdentityUniforms ();
19451960
19461961 void * vertices = vertexBuffer.getBuffer ();
19471962 bool force = mCaches .unbindMeshBuffer ();
1948- mCaches .bindPositionVertexPointer (force, mCaches .currentProgram ->position ,
1949- vertices, isAA ? gAlphaVertexStride : gVertexStride );
1963+ mCaches .bindPositionVertexPointer (true , vertices, isAA ? gAlphaVertexStride : gVertexStride );
19501964 mCaches .resetTexCoordsVertexPointer ();
19511965 mCaches .unbindIndicesBuffer ();
19521966
@@ -1960,7 +1974,7 @@ void OpenGLRenderer::drawConvexPath(const SkPath& path, int color, SkXfermode::M
19601974 glVertexAttribPointer (alphaSlot, 1 , GL_FLOAT, GL_FALSE, gAlphaVertexStride , alphaCoords);
19611975 }
19621976
1963- SkRect bounds = path. getBounds ( );
1977+ SkRect bounds = PathRenderer::computePathBounds (path, paint );
19641978 dirtyLayer (bounds.fLeft , bounds.fTop , bounds.fRight , bounds.fBottom , *mSnapshot ->transform );
19651979
19661980 glDrawArrays (GL_TRIANGLE_STRIP, 0 , vertexBuffer.getSize ());
@@ -2050,7 +2064,7 @@ status_t OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) {
20502064 setupDrawShader ();
20512065 setupDrawBlending (isAA, mode);
20522066 setupDrawProgram ();
2053- setupDrawModelViewIdentity (true );
2067+ setupDrawModelViewIdentity ();
20542068 setupDrawColorUniforms ();
20552069 setupDrawColorFilterUniforms ();
20562070 setupDrawShaderIdentityUniforms ();
@@ -2330,11 +2344,11 @@ status_t OpenGLRenderer::drawShape(float left, float top, const PathTexture* tex
23302344
23312345status_t OpenGLRenderer::drawRoundRect (float left, float top, float right, float bottom,
23322346 float rx, float ry, SkPaint* p) {
2333- if (mSnapshot ->isIgnored () || quickReject (left, top, right, bottom)) {
2347+ if (mSnapshot ->isIgnored () || quickRejectPreStroke (left, top, right, bottom, p )) {
23342348 return DrawGlInfo::kStatusDone ;
23352349 }
23362350
2337- if (p->getStyle () != SkPaint:: kFill_Style ) {
2351+ if (p->getPathEffect () != 0 ) {
23382352 mCaches .activeTexture (0 );
23392353 const PathTexture* texture = mCaches .roundRectShapeCache .getRoundRect (
23402354 right - left, bottom - top, rx, ry, p);
@@ -2343,46 +2357,59 @@ status_t OpenGLRenderer::drawRoundRect(float left, float top, float right, float
23432357
23442358 SkPath path;
23452359 SkRect rect = SkRect::MakeLTRB (left, top, right, bottom);
2360+ if (p->getStyle () == SkPaint::kStrokeAndFill_Style ) {
2361+ float outset = p->getStrokeWidth () / 2 ;
2362+ rect.outset (outset, outset);
2363+ rx += outset;
2364+ ry += outset;
2365+ }
23462366 path.addRoundRect (rect, rx, ry);
2347- drawConvexPath (path, p-> getColor (), getXfermode (p-> getXfermode ()), p-> isAntiAlias () );
2367+ drawConvexPath (path, p);
23482368
23492369 return DrawGlInfo::kStatusDrew ;
23502370}
23512371
23522372status_t OpenGLRenderer::drawCircle (float x, float y, float radius, SkPaint* p) {
2353- if (mSnapshot ->isIgnored () || quickReject (x - radius, y - radius, x + radius, y + radius)) {
2373+ if (mSnapshot ->isIgnored () || quickRejectPreStroke (x - radius, y - radius,
2374+ x + radius, y + radius, p)) {
23542375 return DrawGlInfo::kStatusDone ;
23552376 }
2356-
2357- if (p->getStyle () != SkPaint::kFill_Style ) {
2377+ if (p->getPathEffect () != 0 ) {
23582378 mCaches .activeTexture (0 );
23592379 const PathTexture* texture = mCaches .circleShapeCache .getCircle (radius, p);
23602380 return drawShape (x - radius, y - radius, texture, p);
23612381 }
23622382
23632383 SkPath path;
2364- path.addCircle (x, y, radius);
2365- drawConvexPath (path, p->getColor (), getXfermode (p->getXfermode ()), p->isAntiAlias ());
2384+ if (p->getStyle () == SkPaint::kStrokeAndFill_Style ) {
2385+ path.addCircle (x, y, radius + p->getStrokeWidth () / 2 );
2386+ } else {
2387+ path.addCircle (x, y, radius);
2388+ }
2389+ drawConvexPath (path, p);
23662390
23672391 return DrawGlInfo::kStatusDrew ;
23682392}
23692393
23702394status_t OpenGLRenderer::drawOval (float left, float top, float right, float bottom,
23712395 SkPaint* p) {
2372- if (mSnapshot ->isIgnored () || quickReject (left, top, right, bottom)) {
2396+ if (mSnapshot ->isIgnored () || quickRejectPreStroke (left, top, right, bottom, p )) {
23732397 return DrawGlInfo::kStatusDone ;
23742398 }
23752399
2376- if (p->getStyle () != SkPaint:: kFill_Style ) {
2400+ if (p->getPathEffect () != 0 ) {
23772401 mCaches .activeTexture (0 );
23782402 const PathTexture* texture = mCaches .ovalShapeCache .getOval (right - left, bottom - top, p);
23792403 return drawShape (left, top, texture, p);
23802404 }
23812405
23822406 SkPath path;
23832407 SkRect rect = SkRect::MakeLTRB (left, top, right, bottom);
2408+ if (p->getStyle () == SkPaint::kStrokeAndFill_Style ) {
2409+ rect.outset (p->getStrokeWidth () / 2 , p->getStrokeWidth () / 2 );
2410+ }
23842411 path.addOval (rect);
2385- drawConvexPath (path, p-> getColor (), getXfermode (p-> getXfermode ()), p-> isAntiAlias () );
2412+ drawConvexPath (path, p);
23862413
23872414 return DrawGlInfo::kStatusDrew ;
23882415}
@@ -2402,10 +2429,11 @@ status_t OpenGLRenderer::drawArc(float left, float top, float right, float botto
24022429}
24032430
24042431status_t OpenGLRenderer::drawRect (float left, float top, float right, float bottom, SkPaint* p) {
2405- if (mSnapshot ->isIgnored () || quickReject (left, top, right, bottom)) {
2432+ if (mSnapshot ->isIgnored () || quickRejectPreStroke (left, top, right, bottom, p )) {
24062433 return DrawGlInfo::kStatusDone ;
24072434 }
24082435
2436+ // only fill style is supported by drawConvexPath, since others have to handle joins
24092437 if (p->getStyle () != SkPaint::kFill_Style ) {
24102438 mCaches .activeTexture (0 );
24112439 const PathTexture* texture = mCaches .rectShapeCache .getRect (right - left, bottom - top, p);
@@ -2415,7 +2443,7 @@ status_t OpenGLRenderer::drawRect(float left, float top, float right, float bott
24152443 if (p->isAntiAlias () && !mSnapshot ->transform ->isSimple ()) {
24162444 SkPath path;
24172445 path.addRect (left, top, right, bottom);
2418- drawConvexPath (path, p-> getColor (), getXfermode (p-> getXfermode ()), true );
2446+ drawConvexPath (path, p);
24192447 } else {
24202448 drawColorRect (left, top, right, bottom, p->getColor (), getXfermode (p->getXfermode ()));
24212449 }
0 commit comments