1
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9#include "Test.h"
10#include "SkCanvas.h"
11#include "SkConfig8888.h"
12#include "SkDevice.h"
13
14#if SK_SUPPORT_GPU
15#include "SkGpuDevice.h"
16#endif
17
18
19namespace {
20
21void fillCanvas(SkCanvas* canvas, SkCanvas::Config8888 unpremulConfig) {
22    SkBitmap bmp;
23    bmp.setConfig(SkBitmap::kARGB_8888_Config, 256, 256);
24    bmp.allocPixels();
25    SkAutoLockPixels alp(bmp);
26    uint32_t* pixels = reinterpret_cast<uint32_t*>(bmp.getPixels());
27
28    for (int a = 0; a < 256; ++a) {
29        for (int r = 0; r < 256; ++r) {
30            pixels[a * 256 + r] = SkPackConfig8888(unpremulConfig, a, r, 0, 0);
31        }
32    }
33    canvas->writePixels(bmp, 0, 0, unpremulConfig);
34}
35
36static const SkCanvas::Config8888 gUnpremulConfigs[] = {
37    SkCanvas::kNative_Unpremul_Config8888,
38/**
39 * There is a bug in Ganesh (http://code.google.com/p/skia/issues/detail?id=438)
40 * that causes the readback of pixels from BGRA canvas to an RGBA bitmap to
41 * fail. This should be removed as soon as the issue above is resolved.
42 */
43#if !defined(SK_BUILD_FOR_ANDROID)
44    SkCanvas::kBGRA_Unpremul_Config8888,
45#endif
46    SkCanvas::kRGBA_Unpremul_Config8888,
47};
48
49void PremulAlphaRoundTripTest(skiatest::Reporter* reporter,
50                              GrContext* context) {
51    SkAutoTUnref<SkDevice> device;
52    for (int dtype = 0; dtype < 2; ++dtype) {
53        if (0 == dtype) {
54            device.reset(new SkDevice(SkBitmap::kARGB_8888_Config,
55                                          256,
56                                          256,
57                                          false));
58        } else {
59#if !SK_SUPPORT_GPU || defined(SK_SCALAR_IS_FIXED)
60            // GPU device known not to work in the fixed pt build.
61            continue;
62#else
63            device.reset(new SkGpuDevice(context,
64                                             SkBitmap::kARGB_8888_Config,
65                                             256,
66                                             256));
67#endif
68        }
69        SkCanvas canvas(device);
70
71        SkBitmap readBmp1;
72        readBmp1.setConfig(SkBitmap::kARGB_8888_Config, 256, 256);
73        readBmp1.allocPixels();
74        SkBitmap readBmp2;
75        readBmp2.setConfig(SkBitmap::kARGB_8888_Config, 256, 256);
76        readBmp2.allocPixels();
77
78        for (size_t upmaIdx = 0;
79             upmaIdx < SK_ARRAY_COUNT(gUnpremulConfigs);
80             ++upmaIdx) {
81            fillCanvas(&canvas, gUnpremulConfigs[upmaIdx]);
82            {
83                SkAutoLockPixels alp1(readBmp1);
84                SkAutoLockPixels alp2(readBmp2);
85                sk_bzero(readBmp1.getPixels(), readBmp1.getSafeSize());
86                sk_bzero(readBmp2.getPixels(), readBmp2.getSafeSize());
87            }
88
89            canvas.readPixels(&readBmp1, 0, 0, gUnpremulConfigs[upmaIdx]);
90            canvas.writePixels(readBmp1, 0, 0, gUnpremulConfigs[upmaIdx]);
91            canvas.readPixels(&readBmp2, 0, 0, gUnpremulConfigs[upmaIdx]);
92
93            SkAutoLockPixels alp1(readBmp1);
94            SkAutoLockPixels alp2(readBmp2);
95            uint32_t* pixels1 =
96                reinterpret_cast<uint32_t*>(readBmp1.getPixels());
97            uint32_t* pixels2 =
98                reinterpret_cast<uint32_t*>(readBmp2.getPixels());
99            bool success = true;
100            for (int y = 0; y < 256 && success; ++y) {
101                for (int x = 0; x < 256 && success; ++x) {
102                    int i = y * 256 + x;
103                    REPORTER_ASSERT(reporter, success = pixels1[i] == pixels2[i]);
104                }
105            }
106        }
107    }
108}
109}
110
111#include "TestClassDef.h"
112DEFINE_GPUTESTCLASS("PremulAlphaRoundTripTest", PremulAlphaRoundTripTestClass, PremulAlphaRoundTripTest)
113