1/*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "Test.h"
9
10// This test is specific to the GPU backend.
11#if SK_SUPPORT_GPU && !defined(SK_BUILD_FOR_ANDROID)
12
13#include "GrContextFactory.h"
14#include "SkGpuDevice.h"
15
16static const int X_SIZE = 12;
17static const int Y_SIZE = 12;
18
19DEF_GPUTEST(ReadWriteAlpha, reporter, factory) {
20    for (int type = 0; type < GrContextFactory::kLastGLContextType; ++type) {
21        GrContextFactory::GLContextType glType = static_cast<GrContextFactory::GLContextType>(type);
22        if (!GrContextFactory::IsRenderingGLContext(glType)) {
23            continue;
24        }
25        GrContext* context = factory->get(glType);
26        if (NULL == context) {
27            continue;
28        }
29
30        unsigned char textureData[X_SIZE][Y_SIZE];
31
32        memset(textureData, 0, X_SIZE * Y_SIZE);
33
34        GrSurfaceDesc desc;
35
36        // let Skia know we will be using this texture as a render target
37        desc.fFlags     = kRenderTarget_GrSurfaceFlag;
38        // it is a single channel texture
39        desc.fConfig    = kAlpha_8_GrPixelConfig;
40        desc.fWidth     = X_SIZE;
41        desc.fHeight    = Y_SIZE;
42
43        // We are initializing the texture with zeros here
44        GrTexture* texture = context->textureProvider()->createTexture(desc, false, textureData, 0);
45        if (!texture) {
46            return;
47        }
48
49        SkAutoTUnref<GrTexture> au(texture);
50
51        // create a distinctive texture
52        for (int y = 0; y < Y_SIZE; ++y) {
53            for (int x = 0; x < X_SIZE; ++x) {
54                textureData[x][y] = x*Y_SIZE+y;
55            }
56        }
57
58        // upload the texture
59        texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig,
60                             textureData, 0);
61
62        unsigned char readback[X_SIZE][Y_SIZE];
63
64        // clear readback to something non-zero so we can detect readback failures
65        memset(readback, 0x1, X_SIZE * Y_SIZE);
66
67        // read the texture back
68        texture->readPixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig,
69                            readback, 0);
70
71        // make sure the original & read back versions match
72        bool match = true;
73
74        for (int y = 0; y < Y_SIZE; ++y) {
75            for (int x = 0; x < X_SIZE; ++x) {
76                if (textureData[x][y] != readback[x][y]) {
77                    match = false;
78                }
79            }
80        }
81
82        REPORTER_ASSERT(reporter, match);
83
84        // Now try writing on the single channel texture
85        SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType);
86        SkAutoTUnref<SkBaseDevice> device(SkGpuDevice::Create(texture->asRenderTarget(), &props));
87        SkCanvas canvas(device);
88
89        SkPaint paint;
90
91        const SkRect rect = SkRect::MakeLTRB(-10, -10, X_SIZE + 10, Y_SIZE + 10);
92
93        paint.setColor(SK_ColorWHITE);
94
95        canvas.drawRect(rect, paint);
96
97        texture->readPixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig,
98                            readback, 0);
99
100        match = true;
101
102        for (int y = 0; y < Y_SIZE; ++y) {
103            for (int x = 0; x < X_SIZE; ++x) {
104                if (0xFF != readback[x][y]) {
105                    match = false;
106                }
107            }
108        }
109
110        REPORTER_ASSERT(reporter, match);
111    }
112}
113
114#endif
115