Home | History | Annotate | Download | only in graphics
      1 /*
      2  * Copyright (C) 2012 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1.  Redistributions of source code must retain the above copyright
      8  *     notice, this list of conditions and the following disclaimer.
      9  * 2.  Redistributions in binary form must reproduce the above copyright
     10  *     notice, this list of conditions and the following disclaimer in the
     11  *     documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     16  * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     18  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     19  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
     20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     22  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     23  */
     24 
     25 #include "config.h"
     26 
     27 #include "platform/graphics/GraphicsContext.h"
     28 
     29 #include "platform/graphics/BitmapImage.h"
     30 #include "platform/graphics/DisplayList.h"
     31 #include "platform/graphics/ImageBuffer.h"
     32 #include "platform/graphics/skia/NativeImageSkia.h"
     33 #include "third_party/skia/include/core/SkBitmap.h"
     34 #include "third_party/skia/include/core/SkCanvas.h"
     35 #include "third_party/skia/include/core/SkPicture.h"
     36 #include <gtest/gtest.h>
     37 
     38 using namespace blink;
     39 
     40 namespace {
     41 
     42 #define EXPECT_EQ_RECT(a, b) \
     43     EXPECT_EQ(a.x(), b.x()); \
     44     EXPECT_EQ(a.y(), b.y()); \
     45     EXPECT_EQ(a.width(), b.width()); \
     46     EXPECT_EQ(a.height(), b.height());
     47 
     48 #define EXPECT_PIXELS_MATCH(bitmap, opaqueRect) \
     49 { \
     50     SkAutoLockPixels locker(bitmap); \
     51     for (int y = opaqueRect.y(); y < opaqueRect.maxY(); ++y) \
     52         for (int x = opaqueRect.x(); x < opaqueRect.maxX(); ++x) { \
     53             int alpha = *bitmap.getAddr32(x, y) >> 24; \
     54             EXPECT_EQ(255, alpha); \
     55         } \
     56 }
     57 
     58 #define EXPECT_PIXELS_MATCH_EXACT(bitmap, opaqueRect) \
     59 { \
     60     SkAutoLockPixels locker(bitmap); \
     61     for (int y = 0; y < bitmap.height(); ++y) \
     62         for (int x = 0; x < bitmap.width(); ++x) {     \
     63             int alpha = *bitmap.getAddr32(x, y) >> 24; \
     64             bool opaque = opaqueRect.contains(x, y); \
     65             EXPECT_EQ(opaque, alpha == 255); \
     66         } \
     67 }
     68 
     69 TEST(GraphicsContextTest, trackOpaqueTest)
     70 {
     71     SkBitmap bitmap;
     72     bitmap.allocN32Pixels(400, 400);
     73     bitmap.eraseColor(0);
     74     SkCanvas canvas(bitmap);
     75 
     76     GraphicsContext context(&canvas);
     77     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
     78 
     79     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
     80     Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
     81 
     82     context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
     83     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
     84     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
     85 
     86     context.fillRect(FloatRect(10, 10, 90, 90), alpha, CompositeSourceOver);
     87     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
     88     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
     89 
     90     context.fillRect(FloatRect(99, 13, 10, 90), opaque, CompositePlusLighter);
     91     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
     92     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
     93 
     94     context.fillRect(FloatRect(99, 13, 10, 90), opaque, CompositeSourceIn);
     95     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
     96     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
     97 
     98     context.fillRect(FloatRect(99, 13, 10, 90), alpha, CompositeSourceIn);
     99     EXPECT_EQ_RECT(IntRect(10, 10, 89, 90), context.opaqueRegion().asRect());
    100     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    101 
    102     context.fillRect(FloatRect(8, 8, 3, 90), opaque, CompositeSourceOut);
    103     EXPECT_EQ_RECT(IntRect(11, 10, 88, 90), context.opaqueRegion().asRect());
    104     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    105 
    106     context.fillRect(FloatRect(30, 30, 290, 290), opaque, CompositeSourceOver);
    107     EXPECT_EQ_RECT(IntRect(30, 30, 290, 290), context.opaqueRegion().asRect());
    108     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    109 
    110     context.fillRect(FloatRect(40, 20, 290, 50), opaque, CompositeSourceOver);
    111     EXPECT_EQ_RECT(IntRect(30, 30, 290, 290), context.opaqueRegion().asRect());
    112     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    113 
    114     context.fillRect(FloatRect(10, 10, 390, 50), opaque, CompositeSourceIn);
    115     EXPECT_EQ_RECT(IntRect(30, 30, 290, 290), context.opaqueRegion().asRect());
    116     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    117 
    118     context.fillRect(FloatRect(10, 10, 390, 50), alpha);
    119     EXPECT_EQ_RECT(IntRect(30, 30, 290, 290), context.opaqueRegion().asRect());
    120     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    121 
    122     context.fillRect(FloatRect(10, 10, 390, 50), opaque, CompositeSourceOver);
    123     EXPECT_EQ_RECT(IntRect(30, 10, 290, 310), context.opaqueRegion().asRect());
    124     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    125 }
    126 
    127 TEST(GraphicsContextTest, trackOpaqueClipTest)
    128 {
    129     SkBitmap bitmap;
    130     bitmap.allocN32Pixels(400, 400);
    131     SkCanvas canvas(bitmap);
    132 
    133     GraphicsContext context(&canvas);
    134     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
    135 
    136     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
    137     Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
    138 
    139     context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
    140     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
    141     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    142 
    143     context.clearRect(FloatRect(10, 10, 90, 90));
    144     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
    145 
    146     context.save();
    147     context.clip(FloatRect(0, 0, 10, 10));
    148     context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
    149     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
    150     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    151     context.restore();
    152 
    153     context.clearRect(FloatRect(10, 10, 90, 90));
    154     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
    155 
    156     context.save();
    157     context.clip(FloatRect(20, 20, 10, 10));
    158     context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
    159     EXPECT_EQ_RECT(IntRect(20, 20, 10, 10), context.opaqueRegion().asRect());
    160     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    161 
    162     context.clearRect(FloatRect(10, 10, 90, 90));
    163     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
    164 
    165     // The intersection of the two clips becomes empty.
    166     context.clip(FloatRect(30, 20, 10, 10));
    167     context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
    168     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
    169     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    170     context.restore();
    171 
    172     context.clearRect(FloatRect(10, 10, 90, 90));
    173     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
    174 
    175     // The transform and the clip need to interact correctly (transform first)
    176     context.save();
    177     context.translate(10, 10);
    178     context.clip(FloatRect(20, 20, 10, 10));
    179     context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
    180     EXPECT_EQ_RECT(IntRect(30, 30, 10, 10), context.opaqueRegion().asRect());
    181     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    182     context.restore();
    183 
    184     context.clearRect(FloatRect(10, 10, 90, 90));
    185     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
    186 
    187     // The transform and the clip need to interact correctly (clip first)
    188     context.save();
    189     context.clip(FloatRect(20, 20, 10, 10));
    190     context.translate(10, 10);
    191     context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
    192     EXPECT_EQ_RECT(IntRect(20, 20, 10, 10), context.opaqueRegion().asRect());
    193     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    194     context.restore();
    195 
    196     context.clearRect(FloatRect(10, 10, 90, 90));
    197     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
    198 
    199     Path path;
    200     path.moveTo(FloatPoint(0, 0));
    201     path.addLineTo(FloatPoint(100, 0));
    202 
    203     // Non-rectangular clips just cause the paint to be considered non-opaque.
    204     context.save();
    205     context.clipPath(path, RULE_EVENODD);
    206     context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
    207     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
    208     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    209     context.restore();
    210 
    211     // Another non-rectangular clip.
    212     context.save();
    213     context.clip(IntRect(30, 30, 20, 20));
    214     context.clipOut(IntRect(30, 30, 10, 10));
    215     context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
    216     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
    217     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    218     context.restore();
    219 }
    220 
    221 TEST(GraphicsContextTest, trackImageMask)
    222 {
    223     SkBitmap bitmap;
    224     bitmap.allocN32Pixels(400, 400);
    225     bitmap.eraseColor(0);
    226     SkCanvas canvas(bitmap);
    227 
    228     GraphicsContext context(&canvas);
    229     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
    230 
    231     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
    232     Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
    233 
    234     // Image masks are done by drawing a bitmap into a transparency layer that uses DstIn to mask
    235     // out a transparency layer below that is filled with the mask color. In the end this should
    236     // not be marked opaque.
    237 
    238     context.setCompositeOperation(CompositeSourceOver);
    239     context.beginTransparencyLayer(1);
    240     context.fillRect(FloatRect(10, 10, 10, 10), opaque, CompositeSourceOver);
    241 
    242     context.setCompositeOperation(CompositeDestinationIn);
    243     context.beginTransparencyLayer(1);
    244 
    245     OwnPtr<ImageBuffer> alphaImage = ImageBuffer::create(IntSize(100, 100));
    246     EXPECT_FALSE(!alphaImage);
    247     alphaImage->context()->fillRect(IntRect(0, 0, 100, 100), alpha);
    248 
    249     context.setCompositeOperation(CompositeSourceOver);
    250     context.drawImageBuffer(alphaImage.get(), FloatRect(10, 10, 10, 10));
    251 
    252     context.endLayer();
    253     context.endLayer();
    254 
    255     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
    256     EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
    257 }
    258 
    259 TEST(GraphicsContextTest, trackImageMaskWithOpaqueRect)
    260 {
    261     SkBitmap bitmap;
    262     bitmap.allocN32Pixels(400, 400);
    263     bitmap.eraseColor(0);
    264     SkCanvas canvas(bitmap);
    265 
    266     GraphicsContext context(&canvas);
    267     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
    268 
    269     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
    270     Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
    271 
    272     // Image masks are done by drawing a bitmap into a transparency layer that uses DstIn to mask
    273     // out a transparency layer below that is filled with the mask color. In the end this should
    274     // not be marked opaque.
    275 
    276     context.setCompositeOperation(CompositeSourceOver);
    277     context.beginTransparencyLayer(1);
    278     context.fillRect(FloatRect(10, 10, 10, 10), opaque, CompositeSourceOver);
    279 
    280     context.setCompositeOperation(CompositeDestinationIn);
    281     context.beginTransparencyLayer(1);
    282 
    283     OwnPtr<ImageBuffer> alphaImage = ImageBuffer::create(IntSize(100, 100));
    284     EXPECT_FALSE(!alphaImage);
    285     alphaImage->context()->fillRect(IntRect(0, 0, 100, 100), alpha);
    286 
    287     context.setCompositeOperation(CompositeSourceOver);
    288     context.drawImageBuffer(alphaImage.get(), FloatRect(10, 10, 10, 10));
    289 
    290     // We can't have an opaque mask actually, but we can pretend here like it would look if we did.
    291     context.fillRect(FloatRect(12, 12, 3, 3), opaque, CompositeSourceOver);
    292 
    293     context.endLayer();
    294     context.endLayer();
    295 
    296     EXPECT_EQ_RECT(IntRect(12, 12, 3, 3), context.opaqueRegion().asRect());
    297     EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
    298 }
    299 
    300 TEST(GraphicsContextTest, trackOpaqueJoinTest)
    301 {
    302     SkBitmap bitmap;
    303     bitmap.allocN32Pixels(400, 400);
    304     SkCanvas canvas(bitmap);
    305 
    306     GraphicsContext context(&canvas);
    307     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
    308 
    309     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
    310     Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
    311 
    312     context.fillRect(FloatRect(20, 20, 10, 10), opaque, CompositeSourceOver);
    313     EXPECT_EQ_RECT(IntRect(20, 20, 10, 10), context.opaqueRegion().asRect());
    314     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    315 
    316     // Doesn't join
    317     context.fillRect(FloatRect(31, 20, 10, 10), opaque, CompositeSourceOver);
    318     EXPECT_EQ_RECT(IntRect(20, 20, 10, 10), context.opaqueRegion().asRect());
    319     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    320 
    321     // Does join
    322     context.fillRect(FloatRect(30, 20, 10, 10), opaque, CompositeSourceOver);
    323     EXPECT_EQ_RECT(IntRect(20, 20, 20, 10), context.opaqueRegion().asRect());
    324     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    325 
    326     // Doesn't join
    327     context.fillRect(FloatRect(20, 31, 20, 10), opaque, CompositeSourceOver);
    328     EXPECT_EQ_RECT(IntRect(20, 20, 20, 10), context.opaqueRegion().asRect());
    329     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    330 
    331     // Does join
    332     context.fillRect(FloatRect(20, 30, 20, 10), opaque, CompositeSourceOver);
    333     EXPECT_EQ_RECT(IntRect(20, 20, 20, 20), context.opaqueRegion().asRect());
    334     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    335 
    336     // Doesn't join
    337     context.fillRect(FloatRect(9, 20, 10, 20), opaque, CompositeSourceOver);
    338     EXPECT_EQ_RECT(IntRect(20, 20, 20, 20), context.opaqueRegion().asRect());
    339     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    340 
    341     // Does join
    342     context.fillRect(FloatRect(10, 20, 10, 20), opaque, CompositeSourceOver);
    343     EXPECT_EQ_RECT(IntRect(10, 20, 30, 20), context.opaqueRegion().asRect());
    344     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    345 
    346     // Doesn't join
    347     context.fillRect(FloatRect(10, 9, 30, 10), opaque, CompositeSourceOver);
    348     EXPECT_EQ_RECT(IntRect(10, 20, 30, 20), context.opaqueRegion().asRect());
    349     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    350 
    351     // Does join
    352     context.fillRect(FloatRect(10, 10, 30, 10), opaque, CompositeSourceOver);
    353     EXPECT_EQ_RECT(IntRect(10, 10, 30, 30), context.opaqueRegion().asRect());
    354     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    355 }
    356 
    357 TEST(GraphicsContextTest, trackOpaqueLineTest)
    358 {
    359     SkBitmap bitmap;
    360     bitmap.allocN32Pixels(200, 200);
    361     bitmap.eraseColor(0);
    362     SkCanvas canvas(bitmap);
    363 
    364     GraphicsContext context(&canvas);
    365     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
    366 
    367     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
    368     Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
    369 
    370     context.setShouldAntialias(false);
    371     context.setMiterLimit(0);
    372     context.setStrokeThickness(4);
    373     context.setLineCap(SquareCap);
    374     context.setStrokeStyle(SolidStroke);
    375     context.setCompositeOperation(CompositeSourceOver);
    376 
    377     context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
    378     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
    379     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    380 
    381     context.setCompositeOperation(CompositeSourceIn);
    382 
    383     context.save();
    384     context.setStrokeColor(alpha);
    385     context.drawLine(IntPoint(0, 0), IntPoint(100, 0));
    386     context.restore();
    387     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
    388     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    389 
    390     context.save();
    391     context.setStrokeColor(opaque);
    392     context.drawLine(IntPoint(0, 10), IntPoint(100, 10));
    393     context.restore();
    394     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
    395     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    396 
    397     context.save();
    398     context.setStrokeColor(alpha);
    399     context.drawLine(IntPoint(0, 10), IntPoint(100, 10));
    400     context.restore();
    401     EXPECT_EQ_RECT(IntRect(10, 13, 90, 87), context.opaqueRegion().asRect());
    402     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    403 
    404     context.save();
    405     context.setStrokeColor(alpha);
    406     context.drawLine(IntPoint(0, 11), IntPoint(100, 11));
    407     context.restore();
    408     EXPECT_EQ_RECT(IntRect(10, 14, 90, 86), context.opaqueRegion().asRect());
    409     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    410 
    411     context.setShouldAntialias(true);
    412     context.setCompositeOperation(CompositeSourceOver);
    413 
    414     context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
    415     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
    416     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    417 
    418     context.setCompositeOperation(CompositeSourceIn);
    419 
    420     context.save();
    421     context.setStrokeColor(alpha);
    422     context.drawLine(IntPoint(0, 0), IntPoint(100, 0));
    423     context.restore();
    424     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
    425     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    426 
    427     context.setShouldAntialias(false);
    428     context.save();
    429     context.setStrokeColor(opaque);
    430     context.drawLine(IntPoint(0, 10), IntPoint(100, 10));
    431     context.restore();
    432     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
    433     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    434 
    435     context.setShouldAntialias(true);
    436     context.save();
    437     context.setStrokeColor(opaque);
    438     context.drawLine(IntPoint(0, 10), IntPoint(100, 10));
    439     context.restore();
    440     EXPECT_EQ_RECT(IntRect(10, 13, 90, 87), context.opaqueRegion().asRect());
    441     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    442 
    443     context.save();
    444     context.setStrokeColor(alpha);
    445     context.drawLine(IntPoint(0, 11), IntPoint(100, 11));
    446     context.restore();
    447     EXPECT_EQ_RECT(IntRect(10, 14, 90, 86), context.opaqueRegion().asRect());
    448     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    449 }
    450 
    451 TEST(GraphicsContextTest, trackOpaquePathTest)
    452 {
    453     SkBitmap bitmap;
    454     bitmap.allocN32Pixels(200, 200);
    455     SkCanvas canvas(bitmap);
    456 
    457     GraphicsContext context(&canvas);
    458     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
    459 
    460     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
    461     Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
    462 
    463     context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
    464     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
    465     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    466 
    467     context.setShouldAntialias(false);
    468     context.setMiterLimit(1);
    469     context.setStrokeThickness(5);
    470     context.setLineCap(SquareCap);
    471     context.setStrokeStyle(SolidStroke);
    472     context.setCompositeOperation(CompositeSourceIn);
    473 
    474     Path path;
    475 
    476     context.setFillColor(alpha);
    477     path.moveTo(FloatPoint(0, 0));
    478     path.addLineTo(FloatPoint(100, 0));
    479     context.fillPath(path);
    480     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
    481     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    482     path.clear();
    483 
    484     context.setFillColor(opaque);
    485     path.moveTo(FloatPoint(0, 10));
    486     path.addLineTo(FloatPoint(100, 13));
    487     context.fillPath(path);
    488     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
    489     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    490     path.clear();
    491 
    492     context.setFillColor(alpha);
    493     path.moveTo(FloatPoint(0, 10));
    494     path.addLineTo(FloatPoint(100, 13));
    495     context.fillPath(path);
    496     EXPECT_EQ_RECT(IntRect(10, 13, 90, 87), context.opaqueRegion().asRect());
    497     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    498     path.clear();
    499 
    500     context.setFillColor(alpha);
    501     path.moveTo(FloatPoint(0, 14));
    502     path.addLineTo(FloatPoint(100, 10));
    503     context.fillPath(path);
    504     EXPECT_EQ_RECT(IntRect(10, 14, 90, 86), context.opaqueRegion().asRect());
    505     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    506     path.clear();
    507 }
    508 
    509 TEST(GraphicsContextTest, trackOpaqueImageTest)
    510 {
    511     SkBitmap bitmap;
    512     bitmap.allocN32Pixels(200, 200);
    513     SkCanvas canvas(bitmap);
    514 
    515     GraphicsContext context(&canvas);
    516     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
    517 
    518     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
    519     Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
    520 
    521     SkBitmap opaqueBitmap;
    522     opaqueBitmap.allocN32Pixels(10, 10, true /* opaque */);
    523 
    524     for (int y = 0; y < opaqueBitmap.height(); ++y)
    525         for (int x = 0; x < opaqueBitmap.width(); ++x)
    526             *opaqueBitmap.getAddr32(x, y) = 0xFFFFFFFF;
    527     RefPtr<BitmapImage> opaqueImage = BitmapImage::create(NativeImageSkia::create(opaqueBitmap));
    528     EXPECT_TRUE(opaqueImage->currentFrameKnownToBeOpaque());
    529 
    530     SkBitmap alphaBitmap;
    531     alphaBitmap.allocN32Pixels(10, 10);
    532 
    533     for (int y = 0; y < alphaBitmap.height(); ++y)
    534         for (int x = 0; x < alphaBitmap.width(); ++x)
    535             *alphaBitmap.getAddr32(x, y) = 0x00000000;
    536     RefPtr<BitmapImage> alphaImage = BitmapImage::create(NativeImageSkia::create(alphaBitmap));
    537     EXPECT_FALSE(alphaImage->currentFrameKnownToBeOpaque());
    538 
    539     context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
    540     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
    541     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    542 
    543     context.drawImage(opaqueImage.get(), IntPoint(0, 0));
    544     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
    545     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    546     context.drawImage(alphaImage.get(), IntPoint(0, 0));
    547     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
    548     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    549 
    550     context.drawImage(opaqueImage.get(), IntPoint(5, 5));
    551     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
    552     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    553     context.drawImage(alphaImage.get(), IntPoint(5, 5));
    554     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
    555     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    556 
    557     context.drawImage(opaqueImage.get(), IntPoint(10, 10));
    558     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
    559     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    560     context.drawImage(alphaImage.get(), IntPoint(10, 10));
    561     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
    562     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    563 
    564     context.drawImage(alphaImage.get(), IntPoint(20, 10), CompositeSourceIn);
    565     EXPECT_EQ_RECT(IntRect(10, 20, 90, 80), context.opaqueRegion().asRect());
    566     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    567 
    568     context.save();
    569     context.setAlphaAsFloat(0.5);
    570     context.drawImage(opaqueImage.get(), IntPoint(25, 15), CompositeSourceIn);
    571     context.restore();
    572     EXPECT_EQ_RECT(IntRect(10, 25, 90, 75), context.opaqueRegion().asRect());
    573     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    574 
    575     context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
    576     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
    577     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    578 
    579     context.drawImage(alphaImage.get(), IntPoint(10, 20), CompositeSourceIn);
    580     EXPECT_EQ_RECT(IntRect(20, 10, 80, 90), context.opaqueRegion().asRect());
    581     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    582 
    583     context.save();
    584     context.setAlphaAsFloat(0.5);
    585     context.drawImage(opaqueImage.get(), IntPoint(15, 25), CompositeSourceIn);
    586     context.restore();
    587     EXPECT_EQ_RECT(IntRect(25, 10, 75, 90), context.opaqueRegion().asRect());
    588     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    589 }
    590 
    591 TEST(GraphicsContextTest, trackOpaqueOvalTest)
    592 {
    593     SkBitmap bitmap;
    594     bitmap.allocN32Pixels(200, 200);
    595     bitmap.eraseColor(0);
    596     SkCanvas canvas(bitmap);
    597 
    598     GraphicsContext context(&canvas);
    599     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
    600 
    601     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
    602     Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
    603 
    604     EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect());
    605     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    606 
    607     context.fillEllipse(FloatRect(10, 10, 90, 90));
    608     context.strokeEllipse(FloatRect(10, 10, 90, 90));
    609     EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect());
    610     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    611 
    612     context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
    613     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
    614     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    615 
    616     context.setCompositeOperation(CompositeSourceIn);
    617 
    618     context.setShouldAntialias(false);
    619 
    620     context.setFillColor(opaque);
    621     context.fillEllipse(FloatRect(10, 10, 50, 30));
    622     context.strokeEllipse(FloatRect(10, 10, 50, 30));
    623     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
    624     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    625 
    626     context.setFillColor(alpha);
    627     context.fillEllipse(FloatRect(10, 10, 30, 50));
    628     context.strokeEllipse(FloatRect(10, 10, 30, 50));
    629     EXPECT_EQ_RECT(IntRect(40, 10, 60, 90), context.opaqueRegion().asRect());
    630     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    631 
    632     context.setShouldAntialias(true);
    633 
    634     context.setFillColor(opaque);
    635     context.fillEllipse(FloatRect(10, 10, 50, 30));
    636     context.strokeEllipse(FloatRect(10, 10, 50, 30));
    637     EXPECT_EQ_RECT(IntRect(40, 41, 60, 59), context.opaqueRegion().asRect());
    638     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    639 
    640     context.setFillColor(alpha);
    641     context.fillEllipse(FloatRect(20, 10, 30, 50));
    642     context.strokeEllipse(FloatRect(20, 10, 30, 50));
    643     EXPECT_EQ_RECT(IntRect(51, 41, 49, 59), context.opaqueRegion().asRect());
    644     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    645 }
    646 
    647 TEST(GraphicsContextTest, trackOpaqueRoundedRectTest)
    648 {
    649     SkBitmap bitmap;
    650     bitmap.allocN32Pixels(200, 200);
    651     SkCanvas canvas(bitmap);
    652 
    653     GraphicsContext context(&canvas);
    654     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
    655 
    656     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
    657     Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
    658     IntSize radii(10, 10);
    659 
    660     EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect());
    661     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    662 
    663     context.fillRoundedRect(IntRect(10, 10, 90, 90), radii, radii, radii, radii, opaque);
    664     EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect());
    665     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    666 
    667     context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
    668     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
    669     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    670 
    671     context.setCompositeOperation(CompositeSourceIn);
    672     context.setShouldAntialias(false);
    673 
    674     context.fillRoundedRect(IntRect(10, 10, 50, 30), radii, radii, radii, radii, opaque);
    675     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
    676     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    677 
    678     context.fillRoundedRect(IntRect(10, 10, 30, 50), radii, radii, radii, radii, alpha);
    679     EXPECT_EQ_RECT(IntRect(40, 10, 60, 90), context.opaqueRegion().asRect());
    680     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    681 
    682     context.fillRoundedRect(IntRect(10, 0, 50, 30), radii, radii, radii, radii, alpha);
    683     EXPECT_EQ_RECT(IntRect(40, 30, 60, 70), context.opaqueRegion().asRect());
    684     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    685 
    686     context.fillRoundedRect(IntRect(30, 0, 70, 50), radii, radii, radii, radii, opaque);
    687     EXPECT_EQ_RECT(IntRect(40, 30, 60, 70), context.opaqueRegion().asRect());
    688     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    689 }
    690 
    691 TEST(GraphicsContextTest, trackOpaqueTextTest)
    692 {
    693     int width = 200, height = 200;
    694     SkBitmap bitmap;
    695     bitmap.allocN32Pixels(width, height);
    696     bitmap.eraseColor(0);
    697     SkCanvas canvas(bitmap);
    698     SkRect textRect = SkRect::MakeWH(width, height);
    699 
    700     GraphicsContext context(&canvas);
    701     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
    702 
    703     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
    704     Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
    705 
    706     SkPaint opaquePaint;
    707     opaquePaint.setColor(opaque.rgb());
    708     opaquePaint.setXfermodeMode(SkXfermode::kSrc_Mode);
    709     SkPaint alphaPaint;
    710     alphaPaint.setColor(alpha.rgb());
    711     alphaPaint.setXfermodeMode(SkXfermode::kSrc_Mode);
    712 
    713     SkPoint point = SkPoint::Make(0, 0);
    714 
    715     context.fillRect(FloatRect(50, 50, 50, 50), opaque, CompositeSourceOver);
    716     EXPECT_EQ_RECT(IntRect(50, 50, 50, 50), context.opaqueRegion().asRect());
    717     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    718 
    719     context.drawPosText("A", 1, &point, textRect, opaquePaint);
    720     EXPECT_EQ_RECT(IntRect(50, 50, 50, 50), context.opaqueRegion().asRect());
    721     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    722 
    723     context.drawPosText("A", 1, &point, textRect, alphaPaint);
    724     EXPECT_EQ_RECT(IntRect(0, 0, 0, 0), context.opaqueRegion().asRect());
    725     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    726 
    727     context.fillRect(FloatRect(50, 50, 50, 50), opaque, CompositeSourceOver);
    728     EXPECT_EQ_RECT(IntRect(50, 50, 50, 50), context.opaqueRegion().asRect());
    729     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    730 
    731     context.fillRect(FloatRect(50, 50, 50, 50), opaque, CompositeSourceOver);
    732     EXPECT_EQ_RECT(IntRect(50, 50, 50, 50), context.opaqueRegion().asRect());
    733     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    734 }
    735 
    736 TEST(GraphicsContextTest, trackOpaqueWritePixelsTest)
    737 {
    738     SkBitmap bitmap;
    739     bitmap.allocN32Pixels(200, 200);
    740     bitmap.eraseColor(0);
    741     SkCanvas canvas(bitmap);
    742 
    743     GraphicsContext context(&canvas);
    744     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
    745 
    746     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
    747 
    748     SkBitmap opaqueBitmap;
    749     opaqueBitmap.allocN32Pixels(10, 10, true /* opaque */);
    750     for (int y = 0; y < opaqueBitmap.height(); ++y)
    751         for (int x = 0; x < opaqueBitmap.width(); ++x)
    752             *opaqueBitmap.getAddr32(x, y) = 0xFFFFFFFF;
    753 
    754     SkBitmap alphaBitmap;
    755     alphaBitmap.allocN32Pixels(10, 10);
    756     for (int y = 0; y < alphaBitmap.height(); ++y)
    757         for (int x = 0; x < alphaBitmap.width(); ++x)
    758             *alphaBitmap.getAddr32(x, y) = 0x00000000;
    759 
    760     SkPaint paint;
    761     paint.setXfermodeMode(SkXfermode::kSrc_Mode);
    762 
    763     context.writePixels(opaqueBitmap, 50, 50);
    764     EXPECT_EQ_RECT(IntRect(50, 50, 10, 10), context.opaqueRegion().asRect());
    765     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    766 
    767     context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
    768     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
    769     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    770 
    771     context.writePixels(alphaBitmap, 10, 0);
    772     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
    773     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    774 
    775     context.writePixels(alphaBitmap, 10, 1);
    776     EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect());
    777     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    778 
    779     context.writePixels(alphaBitmap, 0, 10);
    780     EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect());
    781     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    782 
    783     context.writePixels(alphaBitmap, 1, 10);
    784     EXPECT_EQ_RECT(IntRect(11, 11, 89, 89), context.opaqueRegion().asRect());
    785     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    786 }
    787 
    788 TEST(GraphicsContextTest, trackOpaqueDrawBitmapTest)
    789 {
    790     SkBitmap bitmap;
    791     bitmap.allocN32Pixels(200, 200);
    792     bitmap.eraseColor(0);
    793     SkCanvas canvas(bitmap);
    794 
    795     GraphicsContext context(&canvas);
    796     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
    797 
    798     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
    799 
    800     SkBitmap opaqueBitmap;
    801     opaqueBitmap.allocN32Pixels(10, 10, true /* opaque */);
    802     for (int y = 0; y < opaqueBitmap.height(); ++y)
    803         for (int x = 0; x < opaqueBitmap.width(); ++x)
    804             *opaqueBitmap.getAddr32(x, y) = 0xFFFFFFFF;
    805 
    806     SkBitmap alphaBitmap;
    807     alphaBitmap.allocN32Pixels(10, 10);
    808     for (int y = 0; y < alphaBitmap.height(); ++y)
    809         for (int x = 0; x < alphaBitmap.width(); ++x)
    810             *alphaBitmap.getAddr32(x, y) = 0x00000000;
    811 
    812     SkPaint paint;
    813     paint.setXfermodeMode(SkXfermode::kSrc_Mode);
    814 
    815     context.drawBitmap(opaqueBitmap, 10, 10, &paint);
    816     EXPECT_EQ_RECT(IntRect(10, 10, 10, 10), context.opaqueRegion().asRect());
    817     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    818 
    819     context.fillRect(FloatRect(10, 10, 90, 90), opaque, CompositeSourceOver);
    820     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
    821     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    822 
    823     context.drawBitmap(alphaBitmap, 10, 0, &paint);
    824     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
    825     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    826 
    827     context.drawBitmap(alphaBitmap, 10, 1, &paint);
    828     EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect());
    829     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    830 
    831     context.drawBitmap(alphaBitmap, 0, 10, &paint);
    832     EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect());
    833     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    834 
    835     context.drawBitmap(alphaBitmap, 1, 10, &paint);
    836     EXPECT_EQ_RECT(IntRect(11, 11, 89, 89), context.opaqueRegion().asRect());
    837     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    838 }
    839 
    840 TEST(GraphicsContextTest, trackOpaqueDrawBitmapRectTest)
    841 {
    842     SkBitmap bitmap;
    843     bitmap.allocN32Pixels(200, 200);
    844     bitmap.eraseColor(0);
    845     SkCanvas canvas(bitmap);
    846 
    847     GraphicsContext context(&canvas);
    848     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
    849 
    850     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
    851 
    852     SkBitmap opaqueBitmap;
    853     opaqueBitmap.allocN32Pixels(10, 10, true /* opaque */);
    854     for (int y = 0; y < opaqueBitmap.height(); ++y)
    855         for (int x = 0; x < opaqueBitmap.width(); ++x)
    856             *opaqueBitmap.getAddr32(x, y) = 0xFFFFFFFF;
    857 
    858     SkBitmap alphaBitmap;
    859     alphaBitmap.allocN32Pixels(10, 10);
    860     for (int y = 0; y < alphaBitmap.height(); ++y)
    861         for (int x = 0; x < alphaBitmap.width(); ++x)
    862             *alphaBitmap.getAddr32(x, y) = 0x00000000;
    863 
    864     SkPaint paint;
    865     paint.setXfermodeMode(SkXfermode::kSrc_Mode);
    866 
    867     context.drawBitmapRect(opaqueBitmap, 0, SkRect::MakeXYWH(10, 10, 90, 90), &paint);
    868     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
    869     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    870 
    871     context.drawBitmapRect(alphaBitmap, 0, SkRect::MakeXYWH(10, 0, 10, 10), &paint);
    872     EXPECT_EQ_RECT(IntRect(10, 10, 90, 90), context.opaqueRegion().asRect());
    873     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    874 
    875     context.drawBitmapRect(alphaBitmap, 0, SkRect::MakeXYWH(10, 0, 10, 11), &paint);
    876     EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect());
    877     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    878 
    879     context.drawBitmapRect(alphaBitmap, 0, SkRect::MakeXYWH(0, 10, 10, 10), &paint);
    880     EXPECT_EQ_RECT(IntRect(10, 11, 90, 89), context.opaqueRegion().asRect());
    881     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    882 
    883     context.drawBitmapRect(alphaBitmap, 0, SkRect::MakeXYWH(0, 10, 11, 10), &paint);
    884     EXPECT_EQ_RECT(IntRect(11, 11, 89, 89), context.opaqueRegion().asRect());
    885     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    886 }
    887 
    888 TEST(GraphicsContextTest, contextTransparencyLayerTest)
    889 {
    890     SkBitmap bitmap;
    891     bitmap.allocN32Pixels(400, 400);
    892     bitmap.eraseColor(0);
    893     SkCanvas canvas(bitmap);
    894 
    895     GraphicsContext context(&canvas);
    896     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
    897 
    898     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
    899     context.fillRect(FloatRect(20, 20, 10, 10), opaque, CompositeSourceOver);
    900     EXPECT_EQ_RECT(IntRect(20, 20, 10, 10), context.opaqueRegion().asRect());
    901     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    902 
    903     context.clearRect(FloatRect(20, 20, 10, 10));
    904     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
    905 
    906     context.beginTransparencyLayer(0.5);
    907     context.save();
    908     context.fillRect(FloatRect(20, 20, 10, 10), opaque, CompositeSourceOver);
    909     context.restore();
    910     context.endLayer();
    911     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
    912 
    913     context.clearRect(FloatRect(20, 20, 10, 10));
    914     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
    915 
    916     context.beginTransparencyLayer(0.5);
    917     context.fillRect(FloatRect(20, 20, 10, 10), opaque, CompositeSourceOver);
    918     context.endLayer();
    919     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
    920 }
    921 
    922 TEST(GraphicsContextTest, UnboundedDrawsAreClipped)
    923 {
    924     SkBitmap bitmap;
    925     bitmap.allocN32Pixels(400, 400);
    926     bitmap.eraseColor(0);
    927     SkCanvas canvas(bitmap);
    928 
    929     GraphicsContext context(&canvas);
    930     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
    931 
    932     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
    933     Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
    934 
    935     Path path;
    936     context.setShouldAntialias(false);
    937     context.setMiterLimit(1);
    938     context.setStrokeThickness(5);
    939     context.setLineCap(SquareCap);
    940     context.setStrokeStyle(SolidStroke);
    941 
    942     // Make skia unable to compute fast bounds for our paths.
    943     DashArray dashArray;
    944     dashArray.append(1);
    945     dashArray.append(0);
    946     context.setLineDash(dashArray, 0);
    947 
    948     // Make the device opaque in 10,10 40x40.
    949     context.fillRect(FloatRect(10, 10, 40, 40), opaque, CompositeSourceOver);
    950     EXPECT_EQ_RECT(IntRect(10, 10, 40, 40), context.opaqueRegion().asRect());
    951     EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
    952 
    953     // Clip to the left edge of the opaque area.
    954     context.clip(IntRect(10, 10, 10, 40));
    955 
    956     // Draw a path that gets clipped. This should destroy the opaque area but only inside the clip.
    957     context.setCompositeOperation(CompositeSourceOut);
    958     context.setFillColor(alpha);
    959     path.moveTo(FloatPoint(10, 10));
    960     path.addLineTo(FloatPoint(40, 40));
    961     context.strokePath(path);
    962 
    963     EXPECT_EQ_RECT(IntRect(20, 10, 30, 40), context.opaqueRegion().asRect());
    964     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
    965 }
    966 
    967 TEST(GraphicsContextTest, PreserveOpaqueOnlyMattersForFirstLayer)
    968 {
    969     SkBitmap bitmap;
    970     bitmap.allocN32Pixels(400, 400);
    971     bitmap.eraseColor(0);
    972     SkCanvas canvas(bitmap);
    973 
    974     GraphicsContext context(&canvas);
    975     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
    976 
    977     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
    978     Color alpha(0.0f, 0.0f, 0.0f, 0.0f);
    979 
    980     Path path;
    981     context.setShouldAntialias(false);
    982     context.setMiterLimit(1);
    983     context.setStrokeThickness(5);
    984     context.setLineCap(SquareCap);
    985     context.setStrokeStyle(SolidStroke);
    986 
    987     // Make skia unable to compute fast bounds for our paths.
    988     DashArray dashArray;
    989     dashArray.append(1);
    990     dashArray.append(0);
    991     context.setLineDash(dashArray, 0);
    992 
    993     // Make the device opaque in 10,10 40x40.
    994     context.fillRect(FloatRect(10, 10, 40, 40), opaque, CompositeSourceOver);
    995     EXPECT_EQ_RECT(IntRect(10, 10, 40, 40), context.opaqueRegion().asRect());
    996     EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
    997 
    998     // Begin a layer that preserves opaque.
    999     context.setCompositeOperation(CompositeSourceOver);
   1000     context.beginTransparencyLayer(0.5);
   1001 
   1002     // Begin a layer that does not preserve opaque.
   1003     context.setCompositeOperation(CompositeSourceOut);
   1004     context.beginTransparencyLayer(0.5);
   1005 
   1006     // This should not destroy the device opaqueness.
   1007     context.fillRect(FloatRect(10, 10, 40, 40), opaque, CompositeSourceOver);
   1008 
   1009     // This should not destroy the device opaqueness either.
   1010     context.setFillColor(opaque);
   1011     path.moveTo(FloatPoint(10, 10));
   1012     path.addLineTo(FloatPoint(40, 40));
   1013     context.strokePath(path);
   1014 
   1015     context.endLayer();
   1016     context.endLayer();
   1017     EXPECT_EQ_RECT(IntRect(10, 10, 40, 40), context.opaqueRegion().asRect());
   1018     EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
   1019 
   1020     // Now begin a layer that does not preserve opaque and draw through it to the device.
   1021     context.setCompositeOperation(CompositeSourceOut);
   1022     context.beginTransparencyLayer(0.5);
   1023 
   1024     // This should destroy the device opaqueness.
   1025     context.fillRect(FloatRect(10, 10, 40, 40), opaque, CompositeSourceOver);
   1026 
   1027     context.endLayer();
   1028     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
   1029     EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
   1030 
   1031     // Now we draw with a path for which it cannot compute fast bounds. This should destroy the entire opaque region.
   1032 
   1033     context.setCompositeOperation(CompositeSourceOut);
   1034     context.beginTransparencyLayer(0.5);
   1035 
   1036     // This should nuke the device opaqueness.
   1037     context.setFillColor(opaque);
   1038     path.moveTo(FloatPoint(10, 10));
   1039     path.addLineTo(FloatPoint(40, 40));
   1040     context.strokePath(path);
   1041 
   1042     context.endLayer();
   1043     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
   1044     EXPECT_PIXELS_MATCH_EXACT(bitmap, context.opaqueRegion().asRect());
   1045 }
   1046 
   1047 TEST(GraphicsContextTest, OpaqueRegionForLayerWithNonRectDeviceClip)
   1048 {
   1049     SkBitmap bitmap;
   1050     bitmap.allocN32Pixels(100, 100);
   1051     bitmap.eraseColor(0);
   1052     SkCanvas canvas(bitmap);
   1053 
   1054     GraphicsContext context(&canvas);
   1055     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
   1056     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
   1057 
   1058     context.fillRect(FloatRect(30, 30, 90, 90), opaque, CompositeSourceOver);
   1059 
   1060     context.setCompositeOperation(CompositeSourceOver);
   1061     context.beginTransparencyLayer(0.5);
   1062     context.endLayer();
   1063     EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), context.opaqueRegion().asRect());
   1064 
   1065     Path path;
   1066     path.moveTo(FloatPoint(0, 0));
   1067     path.addLineTo(FloatPoint(50, 50));
   1068 
   1069     // For opaque preserving mode and deviceClip is not rect
   1070     // we will not alter opaque rect.
   1071     context.clipPath(path, RULE_EVENODD);
   1072 
   1073     context.setCompositeOperation(CompositeSourceOver);
   1074     context.beginTransparencyLayer(0.5);
   1075     context.endLayer();
   1076     EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), context.opaqueRegion().asRect());
   1077 
   1078     // For non-opaque preserving mode and deviceClip is not rect
   1079     // we will mark opaque rect as empty.
   1080     context.setCompositeOperation(CompositeSourceOut);
   1081     context.beginTransparencyLayer(0.5);
   1082 
   1083     context.endLayer();
   1084     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
   1085 }
   1086 
   1087 TEST(GraphicsContextTest, OpaqueRegionForLayerWithRectDeviceClip)
   1088 {
   1089     SkBitmap bitmap;
   1090     bitmap.allocN32Pixels(100, 100);
   1091     bitmap.eraseColor(0);
   1092     SkCanvas canvas(bitmap);
   1093 
   1094     Color opaque(1.0f, 0.0f, 0.0f, 1.0f);
   1095 
   1096     GraphicsContext context(&canvas);
   1097     context.setRegionTrackingMode(GraphicsContext::RegionTrackingOpaque);
   1098 
   1099     context.fillRect(FloatRect(30, 30, 90, 90), opaque, CompositeSourceOver);
   1100     EXPECT_EQ_RECT(IntRect(30, 30, 70, 70), context.opaqueRegion().asRect());
   1101 
   1102     // For non-opaque preserving mode and deviceClip is rect
   1103     // we will mark device clip rect as non opaque.
   1104     context.setCompositeOperation(CompositeSourceOut);
   1105     context.beginTransparencyLayer(0.5);
   1106     context.endLayer();
   1107     EXPECT_EQ_RECT(IntRect(), context.opaqueRegion().asRect());
   1108     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
   1109 
   1110     context.clip(FloatRect(0, 0, 50, 50));
   1111     context.fillRect(FloatRect(20, 20, 100, 100), opaque, CompositeSourceOver);
   1112 
   1113     // For opaque preserving mode and deviceClip is rect
   1114     // we will intersect device clip rect with src opaque rect.
   1115     context.setCompositeOperation(CompositeSourceOver);
   1116     context.beginTransparencyLayer(0.5);
   1117     context.endLayer();
   1118     EXPECT_EQ_RECT(IntRect(20, 20, 30, 30), context.opaqueRegion().asRect());
   1119     EXPECT_PIXELS_MATCH(bitmap, context.opaqueRegion().asRect());
   1120 }
   1121 
   1122 #define DISPATCH1(c1, c2, op, param1) do { c1.op(param1); c2.op(param1); } while (0);
   1123 #define DISPATCH2(c1, c2, op, param1, param2) do { c1.op(param1, param2); c2.op(param1, param2); } while (0);
   1124 
   1125 TEST(GraphicsContextTest, RecordingTotalMatrix)
   1126 {
   1127     SkBitmap bitmap;
   1128     bitmap.allocN32Pixels(400, 400);
   1129     bitmap.eraseColor(0);
   1130     SkCanvas canvas(bitmap);
   1131     GraphicsContext context(&canvas);
   1132 
   1133     SkCanvas controlCanvas(400, 400);
   1134     GraphicsContext controlContext(&controlCanvas);
   1135 
   1136     EXPECT_EQ(context.getCTM(), controlContext.getCTM());
   1137     DISPATCH2(context, controlContext, scale, 2, 2);
   1138     EXPECT_EQ(context.getCTM(), controlContext.getCTM());
   1139 
   1140     controlContext.save();
   1141     context.beginRecording(FloatRect(0, 0, 200, 200));
   1142     DISPATCH2(context, controlContext, translate, 10, 10);
   1143     EXPECT_EQ(context.getCTM(), controlContext.getCTM());
   1144 
   1145     controlContext.save();
   1146     context.beginRecording(FloatRect(10, 10, 100, 100));
   1147     DISPATCH1(context, controlContext, rotate, 45);
   1148     EXPECT_EQ(context.getCTM(), controlContext.getCTM());
   1149 
   1150     controlContext.restore();
   1151     context.endRecording();
   1152     EXPECT_EQ(context.getCTM(), controlContext.getCTM());
   1153 
   1154     controlContext.restore();
   1155     context.endRecording();
   1156     EXPECT_EQ(context.getCTM(), controlContext.getCTM());
   1157 }
   1158 
   1159 TEST(GraphicsContextTest, RecordingCanvas)
   1160 {
   1161     SkBitmap bitmap;
   1162     bitmap.allocN32Pixels(1, 1);
   1163     bitmap.eraseColor(0);
   1164     SkCanvas canvas(bitmap);
   1165     GraphicsContext context(&canvas);
   1166 
   1167     FloatRect rect(0, 0, 1, 1);
   1168 
   1169     // Two beginRecordings in a row generate two canvases.
   1170     // Unfortunately the new one could be allocated in the same
   1171     // spot as the old one so ref the first one to prolong its life.
   1172     context.beginRecording(rect);
   1173     SkCanvas* canvas1 = context.canvas();
   1174     EXPECT_TRUE(canvas1);
   1175     context.beginRecording(rect);
   1176     SkCanvas* canvas2 = context.canvas();
   1177     EXPECT_TRUE(canvas2);
   1178 
   1179     EXPECT_NE(canvas1, canvas2);
   1180     EXPECT_EQ(1, canvas1->getRefCnt());
   1181 
   1182     // endRecording finally makes the picture accessible
   1183     RefPtr<DisplayList> dl = context.endRecording();
   1184     SkPicture* pic = dl->picture();
   1185     EXPECT_TRUE(pic);
   1186     EXPECT_EQ(1, pic->getRefCnt());
   1187 
   1188     context.endRecording();
   1189 }
   1190 
   1191 } // namespace
   1192