1a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com/* 2a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com * Copyright 2011 Google Inc. 3a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com * 4a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com * Use of this source code is governed by a BSD-style license that can be 5a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com * found in the LICENSE file. 6a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com */ 7a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com 84ee16bfaedb14aff8cf102f1f0722ff2529a9699tfarina@chromium.org#include "SkBitmapDevice.h" 9a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com#include "SkCanvas.h" 10a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com#include "SkConfig8888.h" 114ee16bfaedb14aff8cf102f1f0722ff2529a9699tfarina@chromium.org#include "Test.h" 124cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org#include "sk_tool_utils.h" 13cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com 14cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU 1567b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com#include "GrContextFactory.h" 16a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com#include "SkGpuDevice.h" 17cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif 18a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com 194cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgstatic uint32_t pack_unpremul_rgba(SkColor c) { 204cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org uint32_t packed; 214cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org uint8_t* byte = reinterpret_cast<uint8_t*>(&packed); 224cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org byte[0] = SkColorGetR(c); 234cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org byte[1] = SkColorGetG(c); 244cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org byte[2] = SkColorGetB(c); 254cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org byte[3] = SkColorGetA(c); 264cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return packed; 274cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 284cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 294cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgstatic uint32_t pack_unpremul_bgra(SkColor c) { 304cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org uint32_t packed; 314cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org uint8_t* byte = reinterpret_cast<uint8_t*>(&packed); 324cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org byte[0] = SkColorGetB(c); 334cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org byte[1] = SkColorGetG(c); 344cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org byte[2] = SkColorGetR(c); 354cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org byte[3] = SkColorGetA(c); 364cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org return packed; 374cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 384cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 394cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgtypedef uint32_t (*PackUnpremulProc)(SkColor); 404cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 414cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgconst struct { 42a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkColorType fColorType; 43a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org PackUnpremulProc fPackProc; 444cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} gUnpremul[] = { 45a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org { kRGBA_8888_SkColorType, pack_unpremul_rgba }, 46a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org { kBGRA_8888_SkColorType, pack_unpremul_bgra }, 474cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org}; 484cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org 494cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.orgstatic void fillCanvas(SkCanvas* canvas, SkColorType colorType, PackUnpremulProc proc) { 504cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org // Don't strictly need a bitmap, but its a handy way to allocate the pixels 51a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com SkBitmap bmp; 52deee496cd30070e52556dcb538c2e5eb39b66b81mike@reedtribe.org bmp.allocN32Pixels(256, 256); 53a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com 54a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com for (int a = 0; a < 256; ++a) { 554cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org uint32_t* pixels = bmp.getAddr32(0, a); 56a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com for (int r = 0; r < 256; ++r) { 574cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org pixels[r] = proc(SkColorSetARGB(a, r, 0, 0)); 58a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com } 59a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com } 60a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com 61e5ea500d4714a7d84de2bf913e81be3b65d2de68reed const SkImageInfo info = SkImageInfo::Make(bmp.width(), bmp.height(), 62e5ea500d4714a7d84de2bf913e81be3b65d2de68reed colorType, kUnpremul_SkAlphaType); 634cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org canvas->writePixels(info, bmp.getPixels(), bmp.rowBytes(), 0, 0); 644cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org} 65a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com 664ee16bfaedb14aff8cf102f1f0722ff2529a9699tfarina@chromium.orgDEF_GPUTEST(PremulAlphaRoundTrip, reporter, factory) { 6715a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org const SkImageInfo info = SkImageInfo::MakeN32Premul(256, 256); 6815a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org 69a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com for (int dtype = 0; dtype < 2; ++dtype) { 7067b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com 7167b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com int glCtxTypeCnt = 1; 7267b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com#if SK_SUPPORT_GPU 7367b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com if (0 != dtype) { 7467b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com glCtxTypeCnt = GrContextFactory::kGLContextTypeCnt; 7567b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com } 7667b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com#endif 7767b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com for (int glCtxType = 0; glCtxType < glCtxTypeCnt; ++glCtxType) { 78184ff37c625f8a0588c6e27a24d2284bd70593dfmtklein SkAutoTUnref<SkBaseDevice> device; 7967b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com if (0 == dtype) { 8015a140599942f70e47380e3f700a825c7cece3b4commit-bot@chromium.org device.reset(SkBitmapDevice::Create(info)); 8167b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com } else { 8267b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com#if SK_SUPPORT_GPU 8367b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com GrContextFactory::GLContextType type = 8467b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com static_cast<GrContextFactory::GLContextType>(glCtxType); 8567b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com if (!GrContextFactory::IsRenderingGLContext(type)) { 8667b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com continue; 8767b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com } 88afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon GrContext* ctx = factory->get(type); 89afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon if (NULL == ctx) { 9067b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com continue; 9167b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com } 92afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType); 93afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon device.reset(SkGpuDevice::Create(ctx, SkSurface::kNo_Budgeted, info, 0, &props)); 94cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#else 9567b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com continue; 96cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif 97a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com } 9867b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com SkCanvas canvas(device); 9967b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com 1004cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org for (size_t upmaIdx = 0; upmaIdx < SK_ARRAY_COUNT(gUnpremul); ++upmaIdx) { 1014cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org fillCanvas(&canvas, gUnpremul[upmaIdx].fColorType, gUnpremul[upmaIdx].fPackProc); 102e62513fb9274b65bcd9fecf61acc418dd3949df5skia.committer@gmail.com 103a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org const SkImageInfo info = SkImageInfo::Make(256, 256, gUnpremul[upmaIdx].fColorType, 104a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org kUnpremul_SkAlphaType); 105a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkBitmap readBmp1; 106a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org readBmp1.allocPixels(info); 107a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org SkBitmap readBmp2; 108a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org readBmp2.allocPixels(info); 109a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org 1104cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org readBmp1.eraseColor(0); 1114cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org readBmp2.eraseColor(0); 11267b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com 113a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org canvas.readPixels(&readBmp1, 0, 0); 1144cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org sk_tool_utils::write_pixels(&canvas, readBmp1, 0, 0, gUnpremul[upmaIdx].fColorType, 1154cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org kUnpremul_SkAlphaType); 116a713f9c6f6a06d216d53e268b9c691941053dabfcommit-bot@chromium.org canvas.readPixels(&readBmp2, 0, 0); 117a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com 11867b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com bool success = true; 11967b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com for (int y = 0; y < 256 && success; ++y) { 1204cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org const uint32_t* pixels1 = readBmp1.getAddr32(0, y); 1214cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org const uint32_t* pixels2 = readBmp2.getAddr32(0, y); 12267b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com for (int x = 0; x < 256 && success; ++x) { 123e83909f76c435176b298a2033a0852d1fbd98df4mtklein // We see sporadic failures here. May help to see where it goes wrong. 124e83909f76c435176b298a2033a0852d1fbd98df4mtklein if (pixels1[x] != pixels2[x]) { 125e83909f76c435176b298a2033a0852d1fbd98df4mtklein SkDebugf("%x != %x, x = %d, y = %d\n", pixels1[x], pixels2[x], x, y); 126e83909f76c435176b298a2033a0852d1fbd98df4mtklein } 1274cd9e2169e35cd67ee7358acea6541245e1d1744commit-bot@chromium.org REPORTER_ASSERT(reporter, success = pixels1[x] == pixels2[x]); 12867b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com } 129a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com } 130a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com } 131a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com } 132a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com } 133a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com} 134