< prev index next >

src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLRenderer.m

Print this page




  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 #ifndef HEADLESS
  27 
  28 #include <jlong.h>
  29 #include <jni_util.h>
  30 #include <math.h>
  31 
  32 #include "sun_java2d_metal_MTLRenderer.h"
  33 
  34 #include "MTLRenderer.h"
  35 #include "MTLRenderQueue.h"
  36 #include "MTLSurfaceData.h"
  37 #include "MTLUtils.h"
  38 #import "MTLLayer.h"
  39 
  40 void MTLRenderer_FillParallelogramMetal(
  41     MTLContext* mtlc, id<MTLTexture> dest, jfloat x, jfloat y, jfloat dx1, jfloat dy1, jfloat dx2, jfloat dy2)
  42 {
  43     if (mtlc == NULL || dest == nil)
  44         return;
  45 
  46     J2dTraceLn7(J2D_TRACE_INFO,
  47                 "MTLRenderer_FillParallelogramMetal "
  48                 "(x=%6.2f y=%6.2f "
  49                 "dx1=%6.2f dy1=%6.2f "
  50                 "dx2=%6.2f dy2=%6.2f dst tex=%p)",
  51                 x, y,
  52                 dx1, dy1,
  53                 dx2, dy2, dest);
  54 
  55     struct Vertex verts[PGRAM_VERTEX_COUNT] = {
  56     { {(2.0*x/dest.width) - 1.0,
  57        2.0*(1.0 - y/dest.height) - 1.0, 0.0}},
  58 
  59     { {2.0*(x+dx1)/dest.width - 1.0,
  60       2.0*(1.0 - (y+dy1)/dest.height) - 1.0, 0.0}},
  61 
  62     { {2.0*(x+dx2)/dest.width - 1.0,
  63       2.0*(1.0 - (y+dy2)/dest.height) - 1.0, 0.0}},
  64 
  65     { {2.0*(x+dx1)/dest.width - 1.0,
  66       2.0*(1.0 - (y+dy1)/dest.height) - 1.0, 0.0}},
  67 
  68     { {2.0*(x + dx1 + dx2)/dest.width - 1.0,
  69       2.0*(1.0 - (y+ dy1 + dy2)/dest.height) - 1.0, 0.0}},
  70 
  71     { {2.0*(x+dx2)/dest.width - 1.0,
  72       2.0*(1.0 - (y+dy2)/dest.height) - 1.0, 0.0},
  73     }};
  74 
  75     // Encode render command.
  76     id<MTLRenderCommandEncoder> mtlEncoder = [mtlc createRenderEncoderForDest:dest];
  77     if (mtlEncoder == nil)
  78         return;
  79 
  80     [mtlEncoder setVertexBytes:verts length:sizeof(verts) atIndex:MeshVertexBuffer];
  81     [mtlEncoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount: PGRAM_VERTEX_COUNT];
  82     [mtlEncoder endEncoding];
  83 }
  84 
  85 /**
  86  * Note: Some of the methods in this file apply a "magic number"
  87  * translation to line segments.  The OpenGL specification lays out the
  88  * "diamond exit rule" for line rasterization, but it is loose enough to
  89  * allow for a wide range of line rendering hardware.  (It appears that
  90  * some hardware, such as the Nvidia GeForce2 series, does not even meet
  91  * the spec in all cases.)  As such it is difficult to find a mapping
  92  * between the Java2D and OpenGL line specs that works consistently across
  93  * all hardware combinations.
  94  *
  95  * Therefore the "magic numbers" you see here have been empirically derived
  96  * after testing on a variety of graphics hardware in order to find some
  97  * reasonable middle ground between the two specifications.  The general
  98  * approach is to apply a fractional translation to vertices so that they
  99  * hit pixel centers and therefore touch the same pixels as in our other
 100  * pipelines.  Emphasis was placed on finding values so that MTL lines with
 101  * a slope of +/- 1 hit all the same pixels as our other (software) loops.
 102  * The stepping in other diagonal lines rendered with MTL may deviate
 103  * slightly from those rendered with our software loops, but the most
 104  * important thing is that these magic numbers ensure that all MTL lines


 129     [mtlEncoder setVertexBytes:verts length:sizeof(verts) atIndex:MeshVertexBuffer];
 130     [mtlEncoder drawPrimitives:MTLPrimitiveTypeLine vertexStart:0 vertexCount:2];
 131     [mtlEncoder endEncoding];
 132 }
 133 
 134 void MTLRenderer_DrawRect(MTLContext *mtlc, BMTLSDOps * dstOps, jint x, jint y, jint w, jint h) {
 135     if (mtlc == NULL || dstOps == NULL || dstOps->pTexture == NULL) {
 136         J2dTraceLn(J2D_TRACE_ERROR, "MTLRenderer_DrawRect: dest is null");
 137         return;
 138     }
 139 
 140     id<MTLTexture> dest = dstOps->pTexture;
 141     J2dTraceLn5(J2D_TRACE_INFO, "MTLRenderer_DrawRect (x=%d y=%d w=%d h=%d), dst tex=%p", x, y, w, h, dest);
 142 
 143     // TODO: use DrawParallelogram(x, y, w, h, lw=1, lh=1)
 144     id<MTLRenderCommandEncoder> mtlEncoder = [mtlc createRenderEncoderForDest:dest];
 145     if (mtlEncoder == nil)
 146         return;
 147 
 148     const int verticesCount = 5;
 149     struct Vertex vertices[verticesCount] = {
 150             {{x, y, 0.0}},
 151             {{x + w, y, 0.0}},
 152             {{x + w, y + h, 0.0}},
 153             {{x, y + h, 0.0}},
 154             {{x, y, 0.0}},
 155     };
 156     [mtlEncoder setVertexBytes:vertices length:sizeof(vertices) atIndex:MeshVertexBuffer];
 157     [mtlEncoder drawPrimitives:MTLPrimitiveTypeLineStrip vertexStart:0 vertexCount:verticesCount];
 158     [mtlEncoder endEncoding];
 159 }
 160 
 161 const int POLYLINE_BUF_SIZE = 64;
 162 
 163 static void fillVertex(struct Vertex * vertex, int x, int y) {
 164     vertex->position[0] = x;
 165     vertex->position[1] = y;
 166     vertex->position[2] = 0;
 167 }
 168 
 169 void MTLRenderer_DrawPoly(MTLContext *mtlc, BMTLSDOps * dstOps,


 243      jint transX, jint transY)
 244 {
 245     jint *xPoints, *yPoints;
 246     //TODO
 247     J2dTraceNotImplPrimitive("MTLRenderer_drawPoly");
 248     J2dTraceLn(J2D_TRACE_INFO, "MTLRenderer_drawPoly");
 249 }
 250 
 251 void
 252 MTLRenderer_DrawScanlines(MTLContext *mtlc, BMTLSDOps * dstOps,
 253                           jint scanlineCount, jint *scanlines)
 254 {
 255     //TODO
 256     J2dTraceNotImplPrimitive("MTLRenderer_DrawScanlines");
 257     J2dTraceLn(J2D_TRACE_INFO, "MTLRenderer_DrawScanlines");
 258 }
 259 
 260 void
 261 MTLRenderer_FillRect(MTLContext *mtlc, BMTLSDOps * dstOps, jint x, jint y, jint w, jint h)
 262 {
 263     //TODO
 264     J2dTraceNotImplPrimitive("MTLRenderer_FillRect");
 265     J2dTraceLn(J2D_TRACE_INFO, "MTLRenderer_FillRect");



























 266 }
 267 
 268 const int SPAN_BUF_SIZE=64;
 269 
 270 void
 271 MTLRenderer_FillSpans(MTLContext *mtlc, BMTLSDOps * dstOps, jint spanCount, jint *spans)
 272 {
 273     J2dTraceLn(J2D_TRACE_INFO, "MTLRenderer_FillSpans");
 274     if (mtlc == NULL || dstOps == NULL || dstOps->pTexture == NULL) {
 275         J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLRenderer_FillSpans: dest is null");
 276         return;
 277     }
 278 
 279     while (spanCount > 0) {
 280         __block struct {
 281             jfloat spns[SPAN_BUF_SIZE*4];
 282         } spanStruct;
 283 
 284         __block jfloat sc = spanCount > SPAN_BUF_SIZE ? SPAN_BUF_SIZE : spanCount;
 285 


 353             { {fx11+dx12, fy11+dy12, 0.0},
 354             }};
 355 
 356     // Encode render command.
 357     id<MTLRenderCommandEncoder> mtlEncoder = [mtlc createRenderEncoderForDest:dest];
 358     if (mtlEncoder == nil)
 359         return;
 360 
 361     [mtlEncoder setVertexBytes:verts length:sizeof(verts) atIndex:MeshVertexBuffer];
 362     [mtlEncoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount: PGRAM_VERTEX_COUNT];
 363     [mtlEncoder endEncoding];
 364 }
 365 
 366 void
 367 MTLRenderer_DrawParallelogram(MTLContext *mtlc, BMTLSDOps * dstOps,
 368                               jfloat fx11, jfloat fy11,
 369                               jfloat dx21, jfloat dy21,
 370                               jfloat dx12, jfloat dy12,
 371                               jfloat lwr21, jfloat lwr12)
 372 {
 373     //TODO
 374     J2dTraceNotImplPrimitive("MTLRenderer_DrawParallelogram");
 375     // dx,dy for line width in the "21" and "12" directions.
 376     jfloat ldx21 = dx21 * lwr21;
 377     jfloat ldy21 = dy21 * lwr21;
 378     jfloat ldx12 = dx12 * lwr12;
 379     jfloat ldy12 = dy12 * lwr12;
 380 
 381     // calculate origin of the outer parallelogram
 382     jfloat ox11 = fx11 - (ldx21 + ldx12) / 2.0f;
 383     jfloat oy11 = fy11 - (ldy21 + ldy12) / 2.0f;
 384 
 385     J2dTraceLn8(J2D_TRACE_INFO,
 386                 "MTLRenderer_DrawParallelogram "
 387                 "(x=%6.2f y=%6.2f "
 388                 "dx1=%6.2f dy1=%6.2f lwr1=%6.2f "
 389                 "dx2=%6.2f dy2=%6.2f lwr2=%6.2f)",
 390                 fx11, fy11,
 391                 dx21, dy21, lwr21,
 392                 dx12, dy12, lwr12);
 393 































































 394 }
 395 

 396 static GLhandleARB aaPgramProgram = 0;
 397 
 398 /*
 399  * This shader fills the space between an outer and inner parallelogram.
 400  * It can be used to draw an outline by specifying both inner and outer
 401  * values.  It fills pixels by estimating what portion falls inside the
 402  * outer shape, and subtracting an estimate of what portion falls inside
 403  * the inner shape.  Specifying both inner and outer values produces a
 404  * standard "wide outline".  Specifying an inner shape that falls far
 405  * outside the outer shape allows the same shader to fill the outer
 406  * shape entirely since pixels that fall within the outer shape are never
 407  * inside the inner shape and so they are filled based solely on their
 408  * coverage of the outer shape.
 409  *
 410  * The setup code renders this shader over the bounds of the outer
 411  * shape (or the only shape in the case of a fill operation) and
 412  * sets the texture 0 coordinates so that 0,0=>0,1=>1,1=>1,0 in those
 413  * texture coordinates map to the four corners of the parallelogram.
 414  * Similarly the texture 1 coordinates map the inner shape to the
 415  * unit square as well, but in a different coordinate system.




  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 #ifndef HEADLESS
  27 
  28 #include <jlong.h>
  29 #include <jni_util.h>
  30 #include <math.h>
  31 
  32 #include "sun_java2d_metal_MTLRenderer.h"
  33 
  34 #include "MTLRenderer.h"
  35 #include "MTLRenderQueue.h"
  36 #include "MTLSurfaceData.h"
  37 #include "MTLUtils.h"
  38 #import "MTLLayer.h"
  39 













































  40 /**
  41  * Note: Some of the methods in this file apply a "magic number"
  42  * translation to line segments.  The OpenGL specification lays out the
  43  * "diamond exit rule" for line rasterization, but it is loose enough to
  44  * allow for a wide range of line rendering hardware.  (It appears that
  45  * some hardware, such as the Nvidia GeForce2 series, does not even meet
  46  * the spec in all cases.)  As such it is difficult to find a mapping
  47  * between the Java2D and OpenGL line specs that works consistently across
  48  * all hardware combinations.
  49  *
  50  * Therefore the "magic numbers" you see here have been empirically derived
  51  * after testing on a variety of graphics hardware in order to find some
  52  * reasonable middle ground between the two specifications.  The general
  53  * approach is to apply a fractional translation to vertices so that they
  54  * hit pixel centers and therefore touch the same pixels as in our other
  55  * pipelines.  Emphasis was placed on finding values so that MTL lines with
  56  * a slope of +/- 1 hit all the same pixels as our other (software) loops.
  57  * The stepping in other diagonal lines rendered with MTL may deviate
  58  * slightly from those rendered with our software loops, but the most
  59  * important thing is that these magic numbers ensure that all MTL lines


  84     [mtlEncoder setVertexBytes:verts length:sizeof(verts) atIndex:MeshVertexBuffer];
  85     [mtlEncoder drawPrimitives:MTLPrimitiveTypeLine vertexStart:0 vertexCount:2];
  86     [mtlEncoder endEncoding];
  87 }
  88 
  89 void MTLRenderer_DrawRect(MTLContext *mtlc, BMTLSDOps * dstOps, jint x, jint y, jint w, jint h) {
  90     if (mtlc == NULL || dstOps == NULL || dstOps->pTexture == NULL) {
  91         J2dTraceLn(J2D_TRACE_ERROR, "MTLRenderer_DrawRect: dest is null");
  92         return;
  93     }
  94 
  95     id<MTLTexture> dest = dstOps->pTexture;
  96     J2dTraceLn5(J2D_TRACE_INFO, "MTLRenderer_DrawRect (x=%d y=%d w=%d h=%d), dst tex=%p", x, y, w, h, dest);
  97 
  98     // TODO: use DrawParallelogram(x, y, w, h, lw=1, lh=1)
  99     id<MTLRenderCommandEncoder> mtlEncoder = [mtlc createRenderEncoderForDest:dest];
 100     if (mtlEncoder == nil)
 101         return;
 102 
 103     const int verticesCount = 5;
 104     struct Vertex vertices[5] = {
 105             {{x, y, 0.0}},
 106             {{x + w, y, 0.0}},
 107             {{x + w, y + h, 0.0}},
 108             {{x, y + h, 0.0}},
 109             {{x, y, 0.0}},
 110     };
 111     [mtlEncoder setVertexBytes:vertices length:sizeof(vertices) atIndex:MeshVertexBuffer];
 112     [mtlEncoder drawPrimitives:MTLPrimitiveTypeLineStrip vertexStart:0 vertexCount:verticesCount];
 113     [mtlEncoder endEncoding];
 114 }
 115 
 116 const int POLYLINE_BUF_SIZE = 64;
 117 
 118 static void fillVertex(struct Vertex * vertex, int x, int y) {
 119     vertex->position[0] = x;
 120     vertex->position[1] = y;
 121     vertex->position[2] = 0;
 122 }
 123 
 124 void MTLRenderer_DrawPoly(MTLContext *mtlc, BMTLSDOps * dstOps,


 198      jint transX, jint transY)
 199 {
 200     jint *xPoints, *yPoints;
 201     //TODO
 202     J2dTraceNotImplPrimitive("MTLRenderer_drawPoly");
 203     J2dTraceLn(J2D_TRACE_INFO, "MTLRenderer_drawPoly");
 204 }
 205 
 206 void
 207 MTLRenderer_DrawScanlines(MTLContext *mtlc, BMTLSDOps * dstOps,
 208                           jint scanlineCount, jint *scanlines)
 209 {
 210     //TODO
 211     J2dTraceNotImplPrimitive("MTLRenderer_DrawScanlines");
 212     J2dTraceLn(J2D_TRACE_INFO, "MTLRenderer_DrawScanlines");
 213 }
 214 
 215 void
 216 MTLRenderer_FillRect(MTLContext *mtlc, BMTLSDOps * dstOps, jint x, jint y, jint w, jint h)
 217 {


 218     J2dTraceLn(J2D_TRACE_INFO, "MTLRenderer_FillRect");
 219 
 220     if (mtlc == NULL || dstOps == NULL || dstOps->pTexture == NULL) {
 221         J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLRenderer_FillRect: current dest is null");
 222         return;
 223     }
 224 
 225     struct Vertex verts[PGRAM_VERTEX_COUNT] = {
 226             { {x, y, 0.0}},
 227             { {x, y+h, 0.0}},
 228             { {x+w, y+h, 0.0}},
 229             { {x+w, y+h, 0.0}},
 230             { {x+w, y, 0.0}},
 231             { {x, y, 0.0},
 232     }};
 233 
 234 
 235     id<MTLTexture> dest = dstOps->pTexture;
 236     J2dTraceLn5(J2D_TRACE_INFO, "MTLRenderer_FillRect (x=%d y=%d w=%d h=%d), dst tex=%p", x, y, w, h, dest);
 237 
 238     // Encode render command.
 239     id<MTLRenderCommandEncoder> mtlEncoder = [mtlc createRenderEncoderForDest:dest];
 240     if (mtlEncoder == nil)
 241         return;
 242 
 243     [mtlEncoder setVertexBytes:verts length:sizeof(verts) atIndex:MeshVertexBuffer];
 244     [mtlEncoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount: PGRAM_VERTEX_COUNT];
 245     [mtlEncoder endEncoding];
 246 }
 247 
 248 const int SPAN_BUF_SIZE=64;
 249 
 250 void
 251 MTLRenderer_FillSpans(MTLContext *mtlc, BMTLSDOps * dstOps, jint spanCount, jint *spans)
 252 {
 253     J2dTraceLn(J2D_TRACE_INFO, "MTLRenderer_FillSpans");
 254     if (mtlc == NULL || dstOps == NULL || dstOps->pTexture == NULL) {
 255         J2dRlsTraceLn(J2D_TRACE_ERROR, "MTLRenderer_FillSpans: dest is null");
 256         return;
 257     }
 258 
 259     while (spanCount > 0) {
 260         __block struct {
 261             jfloat spns[SPAN_BUF_SIZE*4];
 262         } spanStruct;
 263 
 264         __block jfloat sc = spanCount > SPAN_BUF_SIZE ? SPAN_BUF_SIZE : spanCount;
 265 


 333             { {fx11+dx12, fy11+dy12, 0.0},
 334             }};
 335 
 336     // Encode render command.
 337     id<MTLRenderCommandEncoder> mtlEncoder = [mtlc createRenderEncoderForDest:dest];
 338     if (mtlEncoder == nil)
 339         return;
 340 
 341     [mtlEncoder setVertexBytes:verts length:sizeof(verts) atIndex:MeshVertexBuffer];
 342     [mtlEncoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount: PGRAM_VERTEX_COUNT];
 343     [mtlEncoder endEncoding];
 344 }
 345 
 346 void
 347 MTLRenderer_DrawParallelogram(MTLContext *mtlc, BMTLSDOps * dstOps,
 348                               jfloat fx11, jfloat fy11,
 349                               jfloat dx21, jfloat dy21,
 350                               jfloat dx12, jfloat dy12,
 351                               jfloat lwr21, jfloat lwr12)
 352 {

 353     J2dTraceNotImplPrimitive("MTLRenderer_DrawParallelogram");
 354     // dx,dy for line width in the "21" and "12" directions.
 355     jfloat ldx21 = dx21 * lwr21;
 356     jfloat ldy21 = dy21 * lwr21;
 357     jfloat ldx12 = dx12 * lwr12;
 358     jfloat ldy12 = dy12 * lwr12;
 359 
 360     // calculate origin of the outer parallelogram
 361     jfloat ox11 = fx11 - (ldx21 + ldx12) / 2.0f;
 362     jfloat oy11 = fy11 - (ldy21 + ldy12) / 2.0f;
 363 
 364     J2dTraceLn8(J2D_TRACE_INFO,
 365                 "MTLRenderer_DrawParallelogram "
 366                 "(x=%6.2f y=%6.2f "
 367                 "dx1=%6.2f dy1=%6.2f lwr1=%6.2f "
 368                 "dx2=%6.2f dy2=%6.2f lwr2=%6.2f)",
 369                 fx11, fy11,
 370                 dx21, dy21, lwr21,
 371                 dx12, dy12, lwr12);
 372 
 373 
 374     // Only need to generate 4 quads if the interior still
 375     // has a hole in it (i.e. if the line width ratio was
 376     // less than 1.0)
 377     if (lwr21 < 1.0f && lwr12 < 1.0f) {
 378 
 379         // Note: "TOP", "BOTTOM", "LEFT" and "RIGHT" here are
 380         // relative to whether the dxNN variables are positive
 381         // and negative.  The math works fine regardless of
 382         // their signs, but for conceptual simplicity the
 383         // comments will refer to the sides as if the dxNN
 384         // were all positive.  "TOP" and "BOTTOM" segments
 385         // are defined by the dxy21 deltas.  "LEFT" and "RIGHT"
 386         // segments are defined by the dxy12 deltas.
 387 
 388         // Each segment includes its starting corner and comes
 389         // to just short of the following corner.  Thus, each
 390         // corner is included just once and the only lengths
 391         // needed are the original parallelogram delta lengths
 392         // and the "line width deltas".  The sides will cover
 393         // the following relative territories:
 394         //
 395         //     T T T T T R
 396         //      L         R
 397         //       L         R
 398         //        L         R
 399         //         L         R
 400         //          L B B B B B
 401 
 402         // TOP segment, to left side of RIGHT edge
 403         // "width" of original pgram, "height" of hor. line size
 404         fx11 = ox11;
 405         fy11 = oy11;
 406         MTLRenderer_FillParallelogram(mtlc, dstOps, fx11, fy11, dx21, dy21, ldx12, ldy12);
 407 
 408         // RIGHT segment, to top of BOTTOM edge
 409         // "width" of vert. line size , "height" of original pgram
 410         fx11 = ox11 + dx21;
 411         fy11 = oy11 + dy21;
 412         MTLRenderer_FillParallelogram(mtlc, dstOps, fx11, fy11, ldx21, ldy21, dx12, dy12);
 413 
 414         // BOTTOM segment, from right side of LEFT edge
 415         // "width" of original pgram, "height" of hor. line size
 416         fx11 = ox11 + dx12 + ldx21;
 417         fy11 = oy11 + dy12 + ldy21;
 418         MTLRenderer_FillParallelogram(mtlc, dstOps, fx11, fy11, dx21, dy21, ldx12, ldy12);
 419 
 420         // LEFT segment, from bottom of TOP edge
 421         // "width" of vert. line size , "height" of inner pgram
 422         fx11 = ox11 + ldx12;
 423         fy11 = oy11 + ldy12;
 424         MTLRenderer_FillParallelogram(mtlc, dstOps, fx11, fy11, ldx21, ldy21, dx12, dy12);
 425     } else {
 426         // The line width ratios were large enough to consume
 427         // the entire hole in the middle of the parallelogram
 428         // so we can just issue one large quad for the outer
 429         // parallelogram.
 430         dx21 += ldx21;
 431         dy21 += ldy21;
 432         dx12 += ldx12;
 433         dy12 += ldy12;
 434         MTLRenderer_FillParallelogram(mtlc, dstOps, ox11, oy11, dx21, dy21, dx12, dy12);
 435     }
 436 }
 437 
 438 
 439 static GLhandleARB aaPgramProgram = 0;
 440 
 441 /*
 442  * This shader fills the space between an outer and inner parallelogram.
 443  * It can be used to draw an outline by specifying both inner and outer
 444  * values.  It fills pixels by estimating what portion falls inside the
 445  * outer shape, and subtracting an estimate of what portion falls inside
 446  * the inner shape.  Specifying both inner and outer values produces a
 447  * standard "wide outline".  Specifying an inner shape that falls far
 448  * outside the outer shape allows the same shader to fill the outer
 449  * shape entirely since pixels that fall within the outer shape are never
 450  * inside the inner shape and so they are filled based solely on their
 451  * coverage of the outer shape.
 452  *
 453  * The setup code renders this shader over the bounds of the outer
 454  * shape (or the only shape in the case of a fill operation) and
 455  * sets the texture 0 coordinates so that 0,0=>0,1=>1,1=>1,0 in those
 456  * texture coordinates map to the four corners of the parallelogram.
 457  * Similarly the texture 1 coordinates map the inner shape to the
 458  * unit square as well, but in a different coordinate system.


< prev index next >