Example #1
0
    /**
     * Create a red & green stripes on black texture
     */
    void createTexture() {
        if (fTextureCreated) {
            return;
        }

        static const int xSize = 16;
        static const int ySize = 16;

        fTexture.allocN32Pixels(xSize, ySize);
        SkPMColor* addr = fTexture.getAddr32(0, 0);

        for (int y = 0; y < ySize; ++y) {
            for (int x = 0; x < xSize; ++x) {
                addr[y*xSize+x] = SkPreMultiplyColor(SK_ColorBLACK);

                if ((y % 5) == 0) {
                    addr[y*xSize+x] = SkPreMultiplyColor(SK_ColorRED);
                }
                if ((x % 7) == 0) {
                    addr[y*xSize+x] = SkPreMultiplyColor(SK_ColorGREEN);
                }
            }
        }

        fTextureCreated = true;
    }
Example #2
0
static bool compare_procs(SkXfermodeProc proc32, SkXfermodeProc4f proc4f) {
    const float kTolerance = 1.0f / 255;

    const SkColor colors[] = {
        0, 0xFF000000, 0xFFFFFFFF, 0x80FF0000
    };

    for (auto s32 : colors) {
        SkPMColor s_pm32 = SkPreMultiplyColor(s32);
        SkPM4f    s_pm4f = SkColor4f::FromColor(s32).premul();
        for (auto d32 : colors) {
            SkPMColor d_pm32 = SkPreMultiplyColor(d32);
            SkPM4f    d_pm4f = SkColor4f::FromColor(d32).premul();

            SkPMColor r32 = proc32(s_pm32, d_pm32);
            SkPM4f    r4f = proc4f(s_pm4f, d_pm4f);

            SkPM4f r32_4f = SkPM4f::FromPMColor(r32);
            if (!nearly_equal(r4f, r32_4f, kTolerance)) {
                return false;
            }
        }
    }
    return true;
}
Example #3
0
/** Create a black and white checked bitmap with 2 1-pixel rings around the outside edge.
    The inner ring is red and the outer ring is blue. */
static bool make_ringed_color_bitmap(TestPixels* result, int width, int height) {
    const SkPMColor kBlue  = SkPreMultiplyColor(SK_ColorBLUE);
    const SkPMColor kRed   = SkPreMultiplyColor(SK_ColorRED);
    const SkPMColor kBlack = SkPreMultiplyColor(SK_ColorBLACK);
    const SkPMColor kWhite = SkPreMultiplyColor(SK_ColorWHITE);
    return make_ringed_bitmap<SkPMColor>(result, width, height, kN32_SkColorType,
                                         kPremul_SkAlphaType, kBlue, kRed, kBlack, kWhite);
}
Example #4
0
	OvalTestView() {
        fSize.set(SK_Scalar1, SK_Scalar1);

        fBitmap.setConfig(SkBitmap::kARGB_8888_Config, kILimit, kILimit);
        fBitmap.allocPixels();

        fInsideColor = SkPreMultiplyColor(SK_ColorRED);
        fOutsideColor = SkPreMultiplyColor(SK_ColorGREEN);
    }
Example #5
0
/** Make the color version of the oversized texture-backed bitmap */
static bool make_ringed_oversized_color_texture_bitmap(GrContext* ctx, TestPixels* result,
                                                       int width, int height) {
    static const SkPMColor kBlue = SkPreMultiplyColor(SK_ColorBLUE);
    static const SkPMColor kRed = SkPreMultiplyColor(SK_ColorRED);
    static const SkPMColor kBlack = SkPreMultiplyColor(SK_ColorBLACK);
    static const SkPMColor kWhite = SkPreMultiplyColor(SK_ColorWHITE);
    static const SkPMColor kGreen = SkPreMultiplyColor(SK_ColorGREEN);
    return make_oversized_texture_bitmap<SkPMColor>(
        ctx, result, width, height, kSkia8888_GrPixelConfig, kBlue, kRed, kBlack, kWhite, kGreen);
}
Example #6
0
DEF_GPUTEST_FOR_NATIVE_CONTEXT(SkImage_NewFromTexture, reporter, context) {
    GrTextureProvider* provider = context->textureProvider();
    const int w = 10;
    const int h = 10;
    SkPMColor storage[w * h];
    const SkPMColor expected0 = SkPreMultiplyColor(SK_ColorRED);
    sk_memset32(storage, expected0, w * h);
    GrSurfaceDesc desc;
    desc.fFlags = kRenderTarget_GrSurfaceFlag;  // needs to be a rendertarget for readpixels();
    desc.fOrigin = kDefault_GrSurfaceOrigin;
    desc.fWidth = w;
    desc.fHeight = h;
    desc.fConfig = kSkia8888_GrPixelConfig;
    desc.fSampleCnt = 0;
    SkAutoTUnref<GrTexture> tex(provider->createTexture(desc, false, storage, w * 4));
    if (!tex) {
        REPORTER_ASSERT(reporter, false);
        return;
    }

    GrBackendTextureDesc backendDesc;
    backendDesc.fConfig = kSkia8888_GrPixelConfig;
    backendDesc.fFlags = kRenderTarget_GrBackendTextureFlag;
    backendDesc.fWidth = w;
    backendDesc.fHeight = h;
    backendDesc.fSampleCnt = 0;
    backendDesc.fTextureHandle = tex->getTextureHandle();
    TextureReleaseChecker releaseChecker;
    SkAutoTUnref<SkImage> refImg(
        SkImage::NewFromTexture(context, backendDesc, kPremul_SkAlphaType,
                                TextureReleaseChecker::Release, &releaseChecker));
    SkAutoTUnref<SkImage> cpyImg(SkImage::NewFromTextureCopy(context, backendDesc,
                                                             kPremul_SkAlphaType));

    check_image_color(reporter, refImg, expected0);
    check_image_color(reporter, cpyImg, expected0);

    // Now lets jam new colors into our "external" texture, and see if the images notice
    const SkPMColor expected1 = SkPreMultiplyColor(SK_ColorBLUE);
    sk_memset32(storage, expected1, w * h);
    tex->writePixels(0, 0, w, h, kSkia8888_GrPixelConfig, storage, GrContext::kFlushWrites_PixelOp);

    // The cpy'd one should still see the old color
#if 0
    // There is no guarantee that refImg sees the new color. We are free to have made a copy. Our
    // write pixels call violated the contract with refImg and refImg is now undefined.
    check_image_color(reporter, refImg, expected1);
#endif
    check_image_color(reporter, cpyImg, expected0);

    // Now exercise the release proc
    REPORTER_ASSERT(reporter, 0 == releaseChecker.fReleaseCount);
    refImg.reset(nullptr); // force a release of the image
    REPORTER_ASSERT(reporter, 1 == releaseChecker.fReleaseCount);
}
Example #7
0
static SkColor xferColor(SkColor src, SkColor dst, SkXfermode::Mode mode) {
    switch (mode) {
        case SkXfermode::kSrc_Mode:
            return src;
        case SkXfermode::kDst_Mode:
            return dst;
        default: {
            SkPMColor pmS = SkPreMultiplyColor(src);
            SkPMColor pmD = SkPreMultiplyColor(dst);
            SkPMColor result = SkXfermode::GetProc(mode)(pmS, pmD);
            return SkUnPreMultiply::PMColorToColor(result);
        }
    }
}
Example #8
0
static inline void test_fast_interp(skiatest::Reporter* reporter) {
    SkRandom r;

    U8CPU a0 = 0;
    U8CPU a255 = 255;
    for (int i = 0; i < 200; i++) {
        SkColor colorSrc = r.nextU();
        SkColor colorDst = r.nextU();
        SkPMColor src = SkPreMultiplyColor(colorSrc);
        SkPMColor dst = SkPreMultiplyColor(colorDst);

        REPORTER_ASSERT(reporter, SkFastFourByteInterp(src, dst, a0) == dst);
        REPORTER_ASSERT(reporter, SkFastFourByteInterp(src, dst, a255) == src);
    }
}
Example #9
0
static void make_bm(SkBitmap* bm) {
    const SkPMColor colors[] = {
        SkPreMultiplyColor(SK_ColorRED), SkPreMultiplyColor(SK_ColorGREEN),
        SkPreMultiplyColor(SK_ColorBLUE), SkPreMultiplyColor(SK_ColorWHITE)
    };
    SkColorTable* ctable = new SkColorTable(colors, 4);
    bm->allocPixels(SkImageInfo::Make(2, 2, kIndex_8_SkColorType,
                                      kOpaque_SkAlphaType),
                    nullptr, ctable);
    ctable->unref();

    *bm->getAddr8(0, 0) = 0;
    *bm->getAddr8(1, 0) = 1;
    *bm->getAddr8(0, 1) = 2;
    *bm->getAddr8(1, 1) = 3;
}
Example #10
0
DEF_TEST(Color4f_colorfilter, reporter) {
    struct {
        SkColorFilter* (*fFact)();
        bool           fSupports4f;
        const char*    fName;
    } recs[] = {
        { make_mode_cf,     true, "mode" },
        { make_mx_cf,       true, "matrix" },
        { make_compose_cf,  true, "compose" },
    };

    // prepare the src
    const int N = 100;
    SkPMColor src4b[N];
    SkPM4f    src4f[N];
    SkRandom rand;
    for (int i = 0; i < N; ++i) {
        src4b[i] = SkPreMultiplyColor(rand.nextU());
        src4f[i] = SkPM4f::FromPMColor(src4b[i]);
    }
    // confirm that our srcs are (nearly) equal
    REPORTER_ASSERT(reporter, compare_spans(src4f, src4b, N));

    for (const auto& rec : recs) {
        SkAutoTUnref<SkColorFilter> filter(rec.fFact());
        SkPMColor dst4b[N];
        filter->filterSpan(src4b, N, dst4b);
        SkPM4f dst4f[N];
        filter->filterSpan4f(src4f, N, dst4f);
        REPORTER_ASSERT(reporter, compare_spans(dst4f, dst4b, N));
    }
}
Example #11
0
SkARGB4444_Blitter::SkARGB4444_Blitter(const SkBitmap& device, const SkPaint& paint)
    : INHERITED(device)
{
    // cache premultiplied versions in 4444
    SkPMColor c = SkPreMultiplyColor(paint.getColor());
    fPMColor16 = SkPixel32ToPixel4444(c);
    if (paint.isDither()) {
        fPMColor16Other = SkDitherPixel32To4444(c);
    } else {
        fPMColor16Other = fPMColor16;
    }

    // cache raw versions in 4444
    fRawColor16 = SkPackARGB4444(0xFF >> 4, SkColorGetR(c) >> 4,
                                 SkColorGetG(c) >> 4, SkColorGetB(c) >> 4);
    if (paint.isDither()) {
        fRawColor16Other = SkDitherARGB32To4444(0xFF, SkColorGetR(c),
                                                SkColorGetG(c), SkColorGetB(c));
    } else {
        fRawColor16Other = fRawColor16;
    }
    
#if 0 /// don't think this assertion is true, but need it be?

    // our dithered color will be the same or more opaque than the original
    // so use dithered to compute our scale
    SkASSERT(SkGetPackedA4444(fPMColor16Other) >= SkGetPackedA4444(fPMColor16));
#endif

    fScale16 = SkAlpha15To16(SkGetPackedA4444(fPMColor16Other));
    if (16 == fScale16) {
        // force the original to also be opaque
        fPMColor16 |= (0xF << SK_A4444_SHIFT);
    }
}
Example #12
0
static SkShader* createChecker() {
//    SkColor colors[] = { 0xFFFDFDFD, 0xFFF4F4F4 };
    SkColor colors[] = { 0xFFFFFFFF, 0xFFFFFFFF };
    SkBitmap bm;
    bm.allocN32Pixels(2, 2);
    bm.lockPixels();
    *bm.getAddr32(0, 0) = *bm.getAddr32(1, 1) = SkPreMultiplyColor(colors[0]);
    *bm.getAddr32(0, 1) = *bm.getAddr32(1, 0) = SkPreMultiplyColor(colors[1]);
    SkShader* s = SkShader::CreateBitmapShader(bm, SkShader::kRepeat_TileMode,
                                               SkShader::kRepeat_TileMode);

    SkMatrix m;
    m.setScale(12, 12);
    s->setLocalMatrix(m);
    return s;
}
Example #13
0
void SkGL::SetColor(SkColor c) {
    SkPMColor pm = SkPreMultiplyColor(c);
    gl_pmcolor(SkGetPackedR32(pm),
               SkGetPackedG32(pm),
               SkGetPackedB32(pm),
               SkGetPackedA32(pm));
}
SkARGB4444_Blitter::SkARGB4444_Blitter(const SkBitmap& device,
                                   const SkPaint& paint) : INHERITED(device) {
    // cache premultiplied versions in 4444
    SkPMColor c = SkPreMultiplyColor(paint.getColor());
    fPMColor16 = SkPixel32ToPixel4444(c);
    if (paint.isDither()) {
        fPMColor16Other = SkDitherPixel32To4444(c);
    } else {
        fPMColor16Other = fPMColor16;
    }

    // cache raw versions in 4444
    fRawColor16 = SkPackARGB4444(0xFF >> 4, SkColorGetR(c) >> 4,
                                 SkColorGetG(c) >> 4, SkColorGetB(c) >> 4);
    if (paint.isDither()) {
        fRawColor16Other = SkDitherARGB32To4444(0xFF, SkColorGetR(c),
                                                SkColorGetG(c), SkColorGetB(c));
    } else {
        fRawColor16Other = fRawColor16;
    }

    fScale16 = SkAlpha15To16(SkGetPackedA4444(fPMColor16Other));
    if (16 == fScale16) {
        // force the original to also be opaque
        fPMColor16 |= (0xF << SK_A4444_SHIFT);
    }
}
Example #15
0
static void FromColor_D32(void* dst, const SkColor src[], int width,
                          int, int) {
    SkPMColor* d = (SkPMColor*)dst;

    for (int i = 0; i < width; i++) {
        *d++ = SkPreMultiplyColor(*src++);
    }
}
Example #16
0
void SkGL::SetRGBA(uint8_t rgba[], const SkColor src[], int count) {
    for (int i = 0; i < count; i++) {
        SkPMColor c = SkPreMultiplyColor(*src++);
        *rgba++ = SkGetPackedR32(c);
        *rgba++ = SkGetPackedG32(c);
        *rgba++ = SkGetPackedB32(c);
        *rgba++ = SkGetPackedA32(c);
    }
}
Example #17
0
static inline void test_premul(skiatest::Reporter* reporter) {
    for (int a = 0; a <= 255; a++) {
        for (int x = 0; x <= 255; x++) {
            SkColor c0 = SkColorSetARGB(a, x, x, x);
            SkPMColor p0 = SkPreMultiplyColor(c0);

            SkColor c1 = SkUnPreMultiply::PMColorToColor(p0);
            SkPMColor p1 = SkPreMultiplyColor(c1);

            // we can't promise that c0 == c1, since c0 -> p0 is a many to one
            // function, however, we can promise that p0 -> c1 -> p1 : p0 == p1
            REPORTER_ASSERT(reporter, p0 == p1);

            {
                int ax = SkMulDiv255Ceiling(x, a);
                REPORTER_ASSERT(reporter, ax <= a);
            }
        }
    }
}
Example #18
0
static void FromColor_D4444(void* dst, const SkColor src[], int width,
                            int x, int y) {
    SkPMColor16* d = (SkPMColor16*)dst;

    DITHER_4444_SCAN(y);
    for (int stop = x + width; x < stop; x++) {
        SkPMColor c = SkPreMultiplyColor(*src++);
        *d++ = SkDitherARGB32To4444(c, DITHER_VALUE(x));
//        *d++ = SkPixel32ToPixel4444(c);
    }
}
Example #19
0
    void onDraw(const int loops, SkCanvas* canvas) override {
        // Unlike blackhole, junk can and probably will be a register.
        uint32_t junk = 0;
        uint32_t seed = 0;
        for (int i = 0; i < loops; i++) {
            SkPMColor colors[4];
        #ifdef SK_DEBUG
            for (int i = 0; i < 4; i++) {
                // Our SkASSERTs will remind us that it's technically required that we premultiply.
                colors[i] = SkPreMultiplyColor(lcg_rand(&seed));
            }
        #else
            // But it's a lot faster not to, and this code won't really mind the non-PM colors.
            (void)lcg_rand(&seed);
            colors[0] = seed + 0;
            colors[1] = seed + 1;
            colors[2] = seed + 2;
            colors[3] = seed + 3;
        #endif

            SkPMFloat fa,fb,fc,fd;
            if (kWide) {
                SkPMFloat::From4PMColors(colors, &fa, &fb, &fc, &fd);
            } else {
                fa = SkPMFloat::FromPMColor(colors[0]);
                fb = SkPMFloat::FromPMColor(colors[1]);
                fc = SkPMFloat::FromPMColor(colors[2]);
                fd = SkPMFloat::FromPMColor(colors[3]);
            }

            SkPMColor back[4];
            switch (kClamp << 1 | kWide) {
                case 0: {
                    back[0] = fa.get();
                    back[1] = fb.get();
                    back[2] = fc.get();
                    back[3] = fd.get();
                } break;
                case 1: SkPMFloat::To4PMColors(fa, fb, fc, fd, back); break;
                case 2: {
                    back[0] = fa.clamped();
                    back[1] = fb.clamped();
                    back[2] = fc.clamped();
                    back[3] = fd.clamped();
                } break;
                case 3: SkPMFloat::ClampTo4PMColors(fa, fb, fc, fd, back); break;
            }
            for (int i = 0; i < 4; i++) {
                junk ^= back[i];
            }
        }
        blackhole ^= junk;
    }
Example #20
0
// https://bug.skia.org/4390
DEF_TEST(ImageFromIndex8Bitmap, r) {
    SkPMColor pmColors[1] = {SkPreMultiplyColor(SK_ColorWHITE)};
    SkBitmap bm;
    SkAutoTUnref<SkColorTable> ctable(
            new SkColorTable(pmColors, SK_ARRAY_COUNT(pmColors)));
    SkImageInfo info =
            SkImageInfo::Make(1, 1, kIndex_8_SkColorType, kPremul_SkAlphaType);
    bm.allocPixels(info, nullptr, ctable);
    SkAutoLockPixels autoLockPixels(bm);
    *bm.getAddr8(0, 0) = 0;
    SkAutoTUnref<SkImage> img(SkImage::NewFromBitmap(bm));
    REPORTER_ASSERT(r, img.get() != nullptr);
}
Example #21
0
static void make_bm(SkBitmap* bm) {
    const SkColor colors[4] = {
        SK_ColorRED, SK_ColorGREEN,
        SK_ColorBLUE, SK_ColorWHITE
    };
    SkPMColor colorsPM[4];
    for (size_t i = 0; i < SK_ARRAY_COUNT(colors); ++i) {
        colorsPM[i] = SkPreMultiplyColor(colors[i]);
    }
    bm->allocN32Pixels(2, 2, true);

    *bm->getAddr32(0, 0) = colorsPM[0];
    *bm->getAddr32(1, 0) = colorsPM[1];
    *bm->getAddr32(0, 1) = colorsPM[2];
    *bm->getAddr32(1, 1) = colorsPM[3];
}
Example #22
0
static void test_peek(skiatest::Reporter* reporter, SkImage* image, bool expectPeekSuccess) {
    SkImageInfo info;
    size_t rowBytes;
    const void* addr = image->peekPixels(&info, &rowBytes);
    bool success = SkToBool(addr);
    REPORTER_ASSERT(reporter, expectPeekSuccess == success);
    if (success) {
        REPORTER_ASSERT(reporter, 20 == info.width());
        REPORTER_ASSERT(reporter, 20 == info.height());
        REPORTER_ASSERT(reporter, kN32_SkColorType == info.colorType());
        REPORTER_ASSERT(reporter, kPremul_SkAlphaType == info.alphaType() ||
                        kOpaque_SkAlphaType == info.alphaType());
        REPORTER_ASSERT(reporter, info.minRowBytes() <= rowBytes);
        REPORTER_ASSERT(reporter, SkPreMultiplyColor(SK_ColorWHITE) == *(const SkPMColor*)addr);
    }
}
Example #23
0
static void test_read_pixels(skiatest::Reporter* reporter, SkImage* image) {
    const SkPMColor expected = SkPreMultiplyColor(SK_ColorWHITE);
    const SkPMColor notExpected = ~expected;

    const int w = 2, h = 2;
    const size_t rowBytes = w * sizeof(SkPMColor);
    SkPMColor pixels[w*h];

    SkImageInfo info;

    info = SkImageInfo::MakeUnknown(w, h);
    REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, 0, 0));

    // out-of-bounds should fail
    info = SkImageInfo::MakeN32Premul(w, h);
    REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, -w, 0));
    REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, 0, -h));
    REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, image->width(), 0));
    REPORTER_ASSERT(reporter, !image->readPixels(info, pixels, rowBytes, 0, image->height()));

    // top-left should succeed
    sk_memset32(pixels, notExpected, w*h);
    REPORTER_ASSERT(reporter, image->readPixels(info, pixels, rowBytes, 0, 0));
    REPORTER_ASSERT(reporter, has_pixels(pixels, w*h, expected));

    // bottom-right should succeed
    sk_memset32(pixels, notExpected, w*h);
    REPORTER_ASSERT(reporter, image->readPixels(info, pixels, rowBytes,
                                                image->width() - w, image->height() - h));
    REPORTER_ASSERT(reporter, has_pixels(pixels, w*h, expected));

    // partial top-left should succeed
    sk_memset32(pixels, notExpected, w*h);
    REPORTER_ASSERT(reporter, image->readPixels(info, pixels, rowBytes, -1, -1));
    REPORTER_ASSERT(reporter, pixels[3] == expected);
    REPORTER_ASSERT(reporter, has_pixels(pixels, w*h - 1, notExpected));

    // partial bottom-right should succeed
    sk_memset32(pixels, notExpected, w*h);
    REPORTER_ASSERT(reporter, image->readPixels(info, pixels, rowBytes,
                                                image->width() - 1, image->height() - 1));
    REPORTER_ASSERT(reporter, pixels[0] == expected);
    REPORTER_ASSERT(reporter, has_pixels(&pixels[1], w*h - 1, notExpected));
}
Example #24
0
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ReimportImageTextureWithMipLevels, reporter, ctxInfo) {
    auto* ctx = ctxInfo.grContext();
    if (!ctx->priv().caps()->mipMapSupport()) {
        return;
    }
    static constexpr auto kCreateWithMipMaps = true;
    auto surf = SkSurface::MakeRenderTarget(
            ctx, SkBudgeted::kYes,
            SkImageInfo::Make(100, 100, kRGBA_8888_SkColorType, kPremul_SkAlphaType), 1,
            kTopLeft_GrSurfaceOrigin, nullptr, kCreateWithMipMaps);
    if (!surf) {
        return;
    }
    surf->getCanvas()->drawColor(SK_ColorDKGRAY);
    auto img = surf->makeImageSnapshot();
    if (!img) {
        return;
    }
    surf.reset();
    GrBackendTexture btex;
    SkImage::BackendTextureReleaseProc texRelease;
    if (!SkImage::MakeBackendTextureFromSkImage(ctx, std::move(img), &btex, &texRelease)) {
        // Not all backends support stealing textures yet.
        // ERRORF(reporter, "Could not turn image into texture");
        return;
    }
    REPORTER_ASSERT(reporter, btex.hasMipMaps());
    // Reimport the texture as an image and perform a downsampling draw with medium quality which
    // should use the upper MIP levels.
    img = SkImage::MakeFromTexture(ctx, btex, kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
                                   kPremul_SkAlphaType, nullptr);
    const auto singlePixelInfo =
            SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
    surf = SkSurface::MakeRenderTarget(ctx, SkBudgeted::kYes, singlePixelInfo, 1,
                                       kTopLeft_GrSurfaceOrigin, nullptr);
    SkPaint paint;
    paint.setFilterQuality(kMedium_SkFilterQuality);
    surf->getCanvas()->drawImageRect(img, SkRect::MakeWH(1, 1), &paint);
    uint32_t pixel;
    surf->readPixels(singlePixelInfo, &pixel, sizeof(uint32_t), 0, 0);
    REPORTER_ASSERT(reporter, pixel == SkPreMultiplyColor(SK_ColorDKGRAY));
    img.reset();
    texRelease(btex);
}
    virtual void onDraw(SkCanvas* canvas) {
        drawBG(canvas);

        SkBitmap sprite;
        sprite.setConfig(SkBitmap::kARGB_8888_Config, 4, 4, 4*sizeof(SkColor));
        const SkColor spriteData[16] = {
            SK_ColorBLACK,  SK_ColorCYAN,    SK_ColorMAGENTA, SK_ColorYELLOW,
            SK_ColorBLACK,  SK_ColorWHITE,   SK_ColorBLACK,   SK_ColorRED,
            SK_ColorGREEN,  SK_ColorBLACK,   SK_ColorWHITE,   SK_ColorBLUE,
            SK_ColorYELLOW, SK_ColorMAGENTA, SK_ColorCYAN,    SK_ColorBLACK
        };
        sprite.allocPixels();
        sprite.lockPixels();
        SkPMColor* addr = sprite.getAddr32(0, 0);
        for (size_t i = 0; i < SK_ARRAY_COUNT(spriteData); ++i) {
            addr[i] = SkPreMultiplyColor(spriteData[i]);
        }
        sprite.unlockPixels();

        // We draw a magnified subrect of the sprite
        // sample interpolation may cause color bleeding around edges
        // the subrect is a pure white area
        SkIRect srcRect;
        SkRect dstRect;
        SkPaint paint;
        paint.setFilterBitmap(true);
        //First row : full texture with and without filtering
        srcRect.setXYWH(0, 0, 4, 4);
        dstRect.setXYWH(SkIntToScalar(0), SkIntToScalar(0)
                        , SkIntToScalar(100), SkIntToScalar(100));
        canvas->drawBitmapRect(sprite, &srcRect, dstRect, &paint);
        dstRect.setXYWH(SkIntToScalar(100), SkIntToScalar(0)
                        , SkIntToScalar(100), SkIntToScalar(100));
        canvas->drawBitmapRect(sprite, &srcRect, dstRect);
        //Second row : sub rect of texture with and without filtering
        srcRect.setXYWH(1, 1, 2, 2);
        dstRect.setXYWH(SkIntToScalar(25), SkIntToScalar(125)
                        , SkIntToScalar(50), SkIntToScalar(50));
        canvas->drawBitmapRect(sprite, &srcRect, dstRect, &paint);
        dstRect.setXYWH(SkIntToScalar(125), SkIntToScalar(125)
                        , SkIntToScalar(50), SkIntToScalar(50));
        canvas->drawBitmapRect(sprite, &srcRect, dstRect);
    }
    void onDraw(const int loops, SkCanvas* canvas) override {
        // Unlike blackhole, junk can and probably will be a register.
        uint32_t junk = 0;
        uint32_t seed = 0;
        for (int i = 0; i < loops; i++) {
            SkPMColor color;
        #ifdef SK_DEBUG
            // Our SkASSERTs will remind us that it's technically required that we premultiply.
            color = SkPreMultiplyColor(lcg_rand(&seed));
        #else
            // But it's a lot faster not to, and this code won't really mind the non-PM colors.
            color = lcg_rand(&seed);
        #endif

            auto f = SkPMFloat::FromPMColor(color);
            SkPMColor back = f.round();
            junk ^= back;
        }
        blackhole ^= junk;
    }
Example #27
0
static void make_bm(SkBitmap* bm) {
    const SkColor colors[4] = {
        SK_ColorRED, SK_ColorGREEN,
        SK_ColorBLUE, SK_ColorWHITE
    };
    SkPMColor colorsPM[4];
    for (size_t i = 0; i < SK_ARRAY_COUNT(colors); ++i) {
        colorsPM[i] = SkPreMultiplyColor(colors[i]);
    }
    SkColorTable* ctable = new SkColorTable(colorsPM, 4);

    bm->setConfig(SkBitmap::kIndex8_Config, 2, 2);
    bm->allocPixels(ctable);
    ctable->unref();

    *bm->getAddr8(0, 0) = 0;
    *bm->getAddr8(1, 0) = 1;
    *bm->getAddr8(0, 1) = 2;
    *bm->getAddr8(1, 1) = 3;
}
Example #28
0
static void apply_premul(const SkImageInfo& info, void* pixels, size_t rowBytes) {
    switch (info.colorType()) {
        case kRGBA_8888_SkColorType:
        case kBGRA_8888_SkColorType:
            break;
        default:
            return; // nothing to do
    }

    // SkColor is not necesarily RGBA or BGRA, but it is one of them on little-endian,
    // and in either case, the alpha-byte is always in the same place, so we can safely call
    // SkPreMultiplyColor()
    //
    SkColor* row = (SkColor*)pixels;
    for (int y = 0; y < info.height(); ++y) {
        for (int x = 0; x < info.width(); ++x) {
            row[x] = SkPreMultiplyColor(row[x]);
        }
    }
}
Example #29
0
static void make_bm(SkBitmap* bm) {
    const SkColor colors[4] = {
        SK_ColorRED, SK_ColorGREEN,
        SK_ColorBLUE, SK_ColorWHITE
    };
    SkPMColor colorsPM[4];
    for (size_t i = 0; i < SK_ARRAY_COUNT(colors); ++i) {
        colorsPM[i] = SkPreMultiplyColor(colors[i]);
    }
    SkColorTable* ctable = new SkColorTable(colorsPM, 4);

    bm->allocPixels(SkImageInfo::Make(2, 2, kIndex_8_SkColorType,
                                      kPremul_SkAlphaType),
                    NULL, ctable);
    ctable->unref();

    *bm->getAddr8(0, 0) = 0;
    *bm->getAddr8(1, 0) = 1;
    *bm->getAddr8(0, 1) = 2;
    *bm->getAddr8(1, 1) = 3;
}
Example #30
0
DEF_TEST(SkPMFloat, r) {
    // Test SkPMColor <-> SkPMFloat
    SkPMColor c = SkPreMultiplyColor(0xFFCC9933);

    SkPMFloat pmf;
    pmf.set(c);
    REPORTER_ASSERT(r, SkScalarNearlyEqual(1.0f, pmf.a()));
    REPORTER_ASSERT(r, SkScalarNearlyEqual(0.8f, pmf.r()));
    REPORTER_ASSERT(r, SkScalarNearlyEqual(0.6f, pmf.g()));
    REPORTER_ASSERT(r, SkScalarNearlyEqual(0.2f, pmf.b()));

    REPORTER_ASSERT(r, c == pmf.get());

    // Test clamping.
    SkPMFloat unclamped;
    unclamped.setA(+2.0f);
    unclamped.setR(+0.2f);
    unclamped.setG(-0.2f);
    unclamped.setB(-5.0f);

    SkPMFloat clamped;
    clamped.set(unclamped.clamped());

    REPORTER_ASSERT(r, SkScalarNearlyEqual(1.0f, clamped.a()));
    REPORTER_ASSERT(r, SkScalarNearlyEqual(0.2f, clamped.r()));
    REPORTER_ASSERT(r, SkScalarNearlyEqual(0.0f, clamped.g()));
    REPORTER_ASSERT(r, SkScalarNearlyEqual(0.0f, clamped.b()));

    // Test SkPMFloat <-> Sk4f conversion.
    Sk4f fs = clamped;
    SkPMFloat scaled = fs.multiply(Sk4f(4,4,4,4));

    REPORTER_ASSERT(r, SkScalarNearlyEqual(4.0f, scaled.a()));
    REPORTER_ASSERT(r, SkScalarNearlyEqual(0.8f, scaled.r()));
    REPORTER_ASSERT(r, SkScalarNearlyEqual(0.0f, scaled.g()));
    REPORTER_ASSERT(r, SkScalarNearlyEqual(0.0f, scaled.b()));
}