示例#1
0
void Bitmap::flipVertical()
{
    std::vector<BYTE> srcPixels(pitch * height);

    memcpy(&srcPixels[0], m_pBits, pitch * height);

    BYTE *pSrcRow = 0;
    BYTE *pDestRow = 0;

    for (int i = 0; i < height; ++i)
    {
        pSrcRow = &srcPixels[(height - 1 - i) * pitch];
        pDestRow = &m_pBits[i * pitch];
        memcpy(pDestRow, pSrcRow, pitch);
    }
}
示例#2
0
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ApplyGamma, reporter, ctxInfo) {
    GrContext* context = ctxInfo.grContext();
    static const int kW = 256;
    static const int kH = 256;
    static const size_t kRowBytes = sizeof(uint32_t) * kW;

    GrSurfaceDesc baseDesc;
    baseDesc.fConfig = kRGBA_8888_GrPixelConfig;
    baseDesc.fWidth = kW;
    baseDesc.fHeight = kH;

    const SkImageInfo ii = SkImageInfo::MakeN32Premul(kW, kH);

    SkAutoTMalloc<uint32_t> srcPixels(kW * kH);
    for (int y = 0; y < kH; ++y) {
        for (int x = 0; x < kW; ++x) {
            srcPixels.get()[y*kW+x] = SkPreMultiplyARGB(x, y, x, 0xFF);
        }
    }

    SkBitmap bm;
    bm.installPixels(ii, srcPixels.get(), kRowBytes);

    SkAutoTMalloc<uint32_t> read(kW * kH);

    // We allow more error on GPUs with lower precision shader variables.
    float error = context->caps()->shaderCaps()->floatPrecisionVaries() ? 1.2f : 0.5f;

    for (auto toSRGB : { false, true }) {
        sk_sp<SkSurface> dst(SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, ii));

        if (!dst) {
            ERRORF(reporter, "Could not create surfaces for copy surface test.");
            continue;
        }

        SkCanvas* dstCanvas = dst->getCanvas();

        dstCanvas->clear(SK_ColorRED);
        dstCanvas->flush();

        SkPaint gammaPaint;
        gammaPaint.setBlendMode(SkBlendMode::kSrc);
        gammaPaint.setColorFilter(toSRGB ? SkColorFilter::MakeLinearToSRGBGamma()
                                         : SkColorFilter::MakeSRGBToLinearGamma());

        dstCanvas->drawBitmap(bm, 0, 0, &gammaPaint);
        dstCanvas->flush();

        sk_memset32(read.get(), 0, kW * kH);
        if (!dstCanvas->readPixels(ii, read.get(), kRowBytes, 0, 0)) {
            ERRORF(reporter, "Error calling readPixels");
            continue;
        }

        bool abort = false;
        // Validate that pixels were copied/transformed correctly.
        for (int y = 0; y < kH && !abort; ++y) {
            for (int x = 0; x < kW && !abort; ++x) {
                uint32_t r = read.get()[y * kW + x];
                uint32_t s = srcPixels.get()[y * kW + x];
                uint32_t expected;
                if (!check_gamma(s, r, toSRGB, error, &expected)) {
                    ERRORF(reporter, "Expected dst %d,%d to contain 0x%08x "
                           "from src 0x%08x and mode %s. Got %08x", x, y, expected, s,
                           toSRGB ? "ToSRGB" : "ToLinear", r);
                    abort = true;
                    break;
                }
            }
        }
    }
}
示例#3
0
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(CopySurface, reporter, ctxInfo) {
    GrContext* context = ctxInfo.grContext();
    static const int kW = 10;
    static const int kH = 10;
    static const size_t kRowBytes = sizeof(uint32_t) * kW;

    SkAutoTMalloc<uint32_t> srcPixels(kW * kH);
    for (int i = 0; i < kW * kH; ++i) {
        srcPixels.get()[i] = i;
    }

    SkAutoTMalloc<uint32_t> dstPixels(kW * kH);
    for (int i = 0; i < kW * kH; ++i) {
        dstPixels.get()[i] = ~i;
    }

    static const SkIRect kSrcRects[] {
        { 0,  0, kW  , kH  },
        {-1, -1, kW+1, kH+1},
        { 1,  1, kW-1, kH-1},
        { 5,  5, 6   , 6   },
    };

    static const SkIPoint kDstPoints[] {
        { 0   ,  0   },
        { 1   ,  1   },
        { kW/2,  kH/4},
        { kW-1,  kH-1},
        { kW  ,  kH  },
        { kW+1,  kH+2},
        {-1   , -1   },
    };

    static const SkImageInfo kImageInfos[] {
        SkImageInfo::Make(kW, kH, kRGBA_8888_SkColorType, kPremul_SkAlphaType),
        SkImageInfo::Make(kW, kH, kBGRA_8888_SkColorType, kPremul_SkAlphaType)
    };

    SkAutoTMalloc<uint32_t> read(kW * kH);

    for (auto sOrigin : {kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin}) {
        for (auto dOrigin : {kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin}) {
            for (auto sRenderable : {GrRenderable::kYes, GrRenderable::kNo}) {
                for (auto dRenderable : {GrRenderable::kYes, GrRenderable::kNo}) {
                    for (auto srcRect : kSrcRects) {
                        for (auto dstPoint : kDstPoints) {
                            for (auto ii: kImageInfos) {
                                auto src = sk_gpu_test::MakeTextureProxyFromData(
                                        context, sRenderable, kW, kH, ii.colorType(), sOrigin,
                                        srcPixels.get(), kRowBytes);
                                auto dst = sk_gpu_test::MakeTextureProxyFromData(
                                        context, dRenderable, kW, kH, ii.colorType(), dOrigin,
                                        dstPixels.get(), kRowBytes);

                                // Should always work if the color type is RGBA, but may not work
                                // for BGRA
                                if (ii.colorType() == kRGBA_8888_SkColorType) {
                                    if (!src || !dst) {
                                        ERRORF(reporter,
                                               "Could not create surfaces for copy surface test.");
                                        continue;
                                    }
                                } else {
                                    GrPixelConfig config =
                                            SkColorType2GrPixelConfig(kBGRA_8888_SkColorType);
                                    if (!context->priv().caps()->isConfigTexturable(config)) {
                                        continue;
                                    }
                                    if (!src || !dst) {
                                        ERRORF(reporter,
                                               "Could not create surfaces for copy surface test.");
                                        continue;
                                    }
                                }

                                sk_sp<GrSurfaceContext> dstContext =
                                        context->priv().makeWrappedSurfaceContext(std::move(dst));

                                bool result = dstContext->copy(src.get(), srcRect, dstPoint);

                                bool expectedResult = true;
                                SkIPoint dstOffset = { dstPoint.fX - srcRect.fLeft,
                                                       dstPoint.fY - srcRect.fTop };
                                SkIRect copiedDstRect = SkIRect::MakeXYWH(dstPoint.fX,
                                                                          dstPoint.fY,
                                                                          srcRect.width(),
                                                                          srcRect.height());

                                SkIRect copiedSrcRect;
                                if (!copiedSrcRect.intersect(srcRect, SkIRect::MakeWH(kW, kH))) {
                                    expectedResult = false;
                                } else {
                                    // If the src rect was clipped, apply same clipping to each side
                                    // of copied dst rect.
                                    copiedDstRect.fLeft += copiedSrcRect.fLeft - srcRect.fLeft;
                                    copiedDstRect.fTop += copiedSrcRect.fTop - srcRect.fTop;
                                    copiedDstRect.fRight -= copiedSrcRect.fRight - srcRect.fRight;
                                    copiedDstRect.fBottom -= copiedSrcRect.fBottom -
                                                             srcRect.fBottom;
                                }
                                if (copiedDstRect.isEmpty() ||
                                    !copiedDstRect.intersect(SkIRect::MakeWH(kW, kH))) {
                                    expectedResult = false;
                                }
                                // To make the copied src rect correct we would apply any dst
                                // clipping back to the src rect, but we don't use it again so
                                // don't bother.
                                if (expectedResult != result) {
                                    ERRORF(reporter, "Expected return value %d from copySurface, "
                                           "got %d.", expectedResult, result);
                                    continue;
                                }

                                if (!expectedResult || !result) {
                                    continue;
                                }

                                sk_memset32(read.get(), 0, kW * kH);
                                if (!dstContext->readPixels(ii, read.get(), kRowBytes, 0, 0)) {
                                    ERRORF(reporter, "Error calling readPixels");
                                    continue;
                                }

                                bool abort = false;
                                // Validate that pixels inside copiedDstRect received the correct
                                // value from src and that those outside were not modified.
                                for (int y = 0; y < kH && !abort; ++y) {
                                    for (int x = 0; x < kW; ++x) {
                                        uint32_t r = read.get()[y * kW + x];
                                        if (copiedDstRect.contains(x, y)) {
                                            int sx = x - dstOffset.fX;
                                            int sy = y - dstOffset.fY;
                                            uint32_t s = srcPixels.get()[sy * kW + sx];
                                            if (s != r) {
                                                ERRORF(reporter, "Expected dst %d,%d to contain "
                                                       "0x%08x copied from src location %d,%d. Got "
                                                       "0x%08x", x, y, s, sx, sy, r);
                                                abort = true;
                                                break;
                                            }
                                        } else {
                                            uint32_t d = dstPixels.get()[y * kW + x];
                                            if (d != r) {
                                                ERRORF(reporter, "Expected dst %d,%d to be "
                                                       "unmodified (0x%08x). Got 0x%08x",
                                                       x, y, d, r);
                                                abort = true;
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
示例#4
0
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(CopySurface, reporter, ctxInfo) {
    GrContext* context = ctxInfo.grContext();
    static const int kW = 10;
    static const int kH = 10;
    static const size_t kRowBytes = sizeof(uint32_t) * kW;

    GrSurfaceDesc baseDesc;
    baseDesc.fConfig = kRGBA_8888_GrPixelConfig;
    baseDesc.fWidth = kW;
    baseDesc.fHeight = kH;

    SkAutoTMalloc<uint32_t> srcPixels(kW * kH);
    for (int i = 0; i < kW * kH; ++i) {
        srcPixels.get()[i] = i;
    }

    SkAutoTMalloc<uint32_t> dstPixels(kW * kH);
    for (int i = 0; i < kW * kH; ++i) {
        dstPixels.get()[i] = ~i;
    }

    static const SkIRect kSrcRects[] {
        { 0,  0, kW  , kH  },
        {-1, -1, kW+1, kH+1},
        { 1,  1, kW-1, kH-1},
        { 5,  5, 6   , 6   },
    };

    static const SkIPoint kDstPoints[] {
        { 0   ,  0   },
        { 1   ,  1   },
        { kW/2,  kH/4},
        { kW-1,  kH-1},
        { kW  ,  kH  },
        { kW+1,  kH+2},
        {-1   , -1   },
    };

    SkAutoTMalloc<uint32_t> read(kW * kH);

    for (auto sOrigin : {kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin}) {
        for (auto dOrigin : {kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin}) {
            for (auto sFlags: {kRenderTarget_GrSurfaceFlag, kNone_GrSurfaceFlags}) {
                for (auto dFlags: {kRenderTarget_GrSurfaceFlag, kNone_GrSurfaceFlags}) {
                    for (auto srcRect : kSrcRects) {
                        for (auto dstPoint : kDstPoints) {
                            GrSurfaceDesc srcDesc = baseDesc;
                            srcDesc.fOrigin = sOrigin;
                            srcDesc.fFlags = sFlags;
                            GrSurfaceDesc dstDesc = baseDesc;
                            dstDesc.fOrigin = dOrigin;
                            dstDesc.fFlags = dFlags;

                            SkAutoTUnref<GrTexture> src(
                                context->textureProvider()->createTexture(srcDesc, SkBudgeted::kNo,
                                                                          srcPixels.get(),
                                                                          kRowBytes));
                            SkAutoTUnref<GrTexture> dst(
                                context->textureProvider()->createTexture(dstDesc, SkBudgeted::kNo,
                                                                          dstPixels.get(),
                                                                          kRowBytes));
                            if (!src || !dst) {
                                ERRORF(reporter,
                                       "Could not create surfaces for copy surface test.");
                                continue;
                            }

                            bool result = context->copySurface(dst, src, srcRect, dstPoint);

                            bool expectedResult = true;
                            SkIPoint dstOffset = { dstPoint.fX - srcRect.fLeft,
                                                   dstPoint.fY - srcRect.fTop };
                            SkIRect copiedDstRect = SkIRect::MakeXYWH(dstPoint.fX,
                                                                      dstPoint.fY,
                                                                      srcRect.width(),
                                                                      srcRect.height());

                            SkIRect copiedSrcRect;
                            if (!copiedSrcRect.intersect(srcRect, SkIRect::MakeWH(kW, kH))) {
                                expectedResult = false;
                            } else {
                                // If the src rect was clipped, apply same clipping to each side of
                                // copied dst rect.
                                copiedDstRect.fLeft += copiedSrcRect.fLeft - srcRect.fLeft;
                                copiedDstRect.fTop += copiedSrcRect.fTop - srcRect.fTop;
                                copiedDstRect.fRight -= copiedSrcRect.fRight - srcRect.fRight;
                                copiedDstRect.fBottom -= copiedSrcRect.fBottom - srcRect.fBottom;
                            }
                            if (copiedDstRect.isEmpty() ||
                                !copiedDstRect.intersect(SkIRect::MakeWH(kW, kH))) {
                                expectedResult = false;
                            }
                            // To make the copied src rect correct we would apply any dst clipping
                            // back to the src rect, but we don't use it again so don't bother.
                            if (expectedResult != result) {
                                ERRORF(reporter, "Expected return value %d from copySurface, got "
                                       "%d.", expectedResult, result);
                                continue;
                            }

                            if (!expectedResult || !result) {
                                continue;
                            }

                            sk_memset32(read.get(), 0, kW * kH);
                            if (!dst->readPixels(0, 0, kW, kH, baseDesc.fConfig, read.get(),
                                                 kRowBytes)) {
                                ERRORF(reporter, "Error calling readPixels");
                                continue;
                            }

                            bool abort = false;
                            // Validate that pixels inside copiedDstRect received the correct value
                            // from src and that those outside were not modified.
                            for (int y = 0; y < kH && !abort; ++y) {
                                for (int x = 0; x < kW; ++x) {
                                    uint32_t r = read.get()[y * kW + x];
                                    if (copiedDstRect.contains(x, y)) {
                                        int sx = x - dstOffset.fX;
                                        int sy = y - dstOffset.fY;
                                        uint32_t s = srcPixels.get()[sy * kW + sx];
                                        if (s != r) {
                                            ERRORF(reporter, "Expected dst %d,%d to contain "
                                                   "0x%08x copied from src location %d,%d. Got "
                                                   "0x%08x", x, y, s, sx, sy, r);
                                            abort = true;
                                            break;
                                        }
                                    } else {
                                        uint32_t d = dstPixels.get()[y * kW + x];
                                        if (d != r) {
                                            ERRORF(reporter, "Expected dst %d,%d to be unmodified ("
                                                   "0x%08x). Got 0x%08x", x, y, d, r);
                                            abort = true;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}