template <bool doSwapRB, AlphaVerb doAlpha> uint32_t convert32(uint32_t c) { if (doSwapRB) { c = SkSwizzle_RB(c); } // Lucky for us, in both RGBA and BGRA, the alpha component is always in the same place, so // we can perform premul or unpremul the same way without knowing the swizzles for RGB. switch (doAlpha) { case kNothing_AlphaVerb: // no change break; case kPremul_AlphaVerb: c = SkPreMultiplyARGB(SkGetPackedA32(c), SkGetPackedR32(c), SkGetPackedG32(c), SkGetPackedB32(c)); break; case kUnpremul_AlphaVerb: c = SkUnPreMultiply::UnPreMultiplyPreservingByteOrder(c); break; } return c; }
/** Tests calling copyTo on a texture backed bitmap. Tests that all BGRA_8888/RGBA_8888 combinations of src and dst work. This test should be removed when SkGrPixelRef is removed. */ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(BitmapCopy_Texture, reporter, ctxInfo) { static const SkPMColor kData[] = { 0xFF112233, 0xAF224499, 0xEF004466, 0x80773311 }; uint32_t swizData[SK_ARRAY_COUNT(kData)]; for (size_t i = 0; i < SK_ARRAY_COUNT(kData); ++i) { swizData[i] = SkSwizzle_RB(kData[i]); } static const GrPixelConfig kSrcConfigs[] = { kRGBA_8888_GrPixelConfig, kBGRA_8888_GrPixelConfig, }; for (size_t srcC = 0; srcC < SK_ARRAY_COUNT(kSrcConfigs); ++srcC) { for (int rt = 0; rt < 2; ++rt) { GrSurfaceDesc desc; desc.fConfig = kSrcConfigs[srcC]; desc.fFlags = rt ? kRenderTarget_GrSurfaceFlag : kNone_GrSurfaceFlags; desc.fWidth = 2; desc.fHeight = 2; desc.fOrigin = kTopLeft_GrSurfaceOrigin; const void* srcData = (kSkia8888_GrPixelConfig == desc.fConfig) ? kData : swizData; SkAutoTUnref<GrTexture> texture( ctxInfo.grContext()->textureProvider()->createTexture(desc, SkBudgeted::kNo, srcData, 0)); if (!texture) { continue; } SkBitmap srcBmp; GrWrapTextureInBitmap(texture, 2, 2, false, &srcBmp); if (srcBmp.isNull()) { ERRORF(reporter, "Could not wrap texture in bitmap."); continue; } static const SkColorType kDstCTs[] = { kRGBA_8888_SkColorType, kBGRA_8888_SkColorType }; for (size_t dCT = 0; dCT < SK_ARRAY_COUNT(kDstCTs); ++dCT) { SkBitmap dstBmp; if (!srcBmp.copyTo(&dstBmp, kDstCTs[dCT])) { ERRORF(reporter, "CopyTo failed."); } if (dstBmp.colorType() != kDstCTs[dCT]) { ERRORF(reporter, "SkBitmap::CopyTo did not respect passed in color type."); } SkAutoLockPixels alp(dstBmp); uint8_t* dstBmpPixels = static_cast<uint8_t*>(dstBmp.getPixels()); const uint32_t* refData; #if defined(SK_PMCOLOR_IS_RGBA) refData = (kRGBA_8888_SkColorType == dstBmp.colorType()) ? kData : swizData; #elif defined(SK_PMCOLOR_IS_BGRA) refData = (kBGRA_8888_SkColorType == dstBmp.colorType()) ? kData : swizData; #else #error "PM Color must be BGRA or RGBA to use GPU backend." #endif bool foundError = false; for (int y = 0; y < 2 && !foundError; ++y) { uint32_t* dstBmpRow = reinterpret_cast<uint32_t*>(dstBmpPixels); for (int x = 0; x < 2 && !foundError; ++x) { if (refData[2 * y + x] != dstBmpRow[x]) { ERRORF(reporter, "Expected pixel 0x%08x, found 0x%08x.", refData[2 * y + x], dstBmpRow[x]); foundError = true; } } dstBmpPixels += dstBmp.rowBytes(); } } } } }