Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright 2015 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 #if SK_SUPPORT_GPU
     10 #include "GrContext.h"
     11 #include "GrDrawContext.h"
     12 #include "gl/GrGLGpu.h"
     13 #include "gl/GrGLUtil.h"
     14 #include "gl/SkGLContext.h"
     15 
     16 static void test_read_pixels(skiatest::Reporter* reporter, GrContext* context,
     17                              GrTexture* rectangleTexture, uint32_t expectedPixelValues[]) {
     18     int pixelCnt = rectangleTexture->width() * rectangleTexture->height();
     19     SkAutoTMalloc<uint32_t> pixels(pixelCnt);
     20     memset(pixels.get(), 0, sizeof(uint32_t)*pixelCnt);
     21     bool read = rectangleTexture->readPixels(0, 0, rectangleTexture->width(),
     22                                             rectangleTexture->height(), kRGBA_8888_GrPixelConfig,
     23                                             pixels.get());
     24     if (!read) {
     25         ERRORF(reporter, "Error reading rectangle texture.");
     26     }
     27     for (int i = 0; i < pixelCnt; ++i) {
     28         if (pixels.get()[i] != expectedPixelValues[i]) {
     29             ERRORF(reporter, "Error, rectangle texture pixel value %d should be 0x%08x,"
     30                              " got 0x%08x.", i, expectedPixelValues[i], pixels.get()[i]);
     31             break;
     32         }
     33     }
     34 }
     35 
     36 static void test_write_pixels(skiatest::Reporter* reporter, GrContext* context,
     37                               GrTexture* rectangleTexture) {
     38     int pixelCnt = rectangleTexture->width() * rectangleTexture->height();
     39     SkAutoTMalloc<uint32_t> pixels(pixelCnt);
     40     for (int y = 0; y < rectangleTexture->width(); ++y) {
     41         for (int x = 0; x < rectangleTexture->height(); ++x) {
     42             pixels.get()[y * rectangleTexture->width() + x] = GrColorPackRGBA(x, y, x + y, x * y);
     43         }
     44     }
     45     bool write = rectangleTexture->writePixels(0, 0, rectangleTexture->width(),
     46                                                rectangleTexture->height(), kRGBA_8888_GrPixelConfig,
     47                                                pixels.get());
     48     if (!write) {
     49         ERRORF(reporter, "Error writing to rectangle texture.");
     50     }
     51     test_read_pixels(reporter, context, rectangleTexture, pixels.get());
     52 }
     53 
     54 static void test_copy_surface_src(skiatest::Reporter* reporter, GrContext* context,
     55                                   GrTexture* rectangleTexture, uint32_t expectedPixelValues[]) {
     56     GrSurfaceDesc copyDstDesc;
     57     copyDstDesc.fConfig = kRGBA_8888_GrPixelConfig;
     58     copyDstDesc.fWidth = rectangleTexture->width();
     59     copyDstDesc.fHeight = rectangleTexture->height();
     60     copyDstDesc.fFlags = kRenderTarget_GrSurfaceFlag;
     61     SkAutoTUnref<GrTexture> dst(context->textureProvider()->createTexture(
     62             copyDstDesc, SkBudgeted::kYes));
     63     context->copySurface(dst, rectangleTexture);
     64     test_read_pixels(reporter, context, dst, expectedPixelValues);
     65 }
     66 
     67 static void test_copy_surface_dst(skiatest::Reporter* reporter, GrContext* context,
     68                                   GrTexture* rectangleTexture) {
     69     int pixelCnt = rectangleTexture->width() * rectangleTexture->height();
     70     SkAutoTMalloc<uint32_t> pixels(pixelCnt);
     71     for (int y = 0; y < rectangleTexture->width(); ++y) {
     72         for (int x = 0; x < rectangleTexture->height(); ++x) {
     73             pixels.get()[y * rectangleTexture->width() + x] = GrColorPackRGBA(y, x, x * y, x *+ y);
     74         }
     75     }
     76 
     77     GrSurfaceDesc copySrcDesc;
     78     copySrcDesc.fConfig = kRGBA_8888_GrPixelConfig;
     79     copySrcDesc.fWidth = rectangleTexture->width();
     80     copySrcDesc.fHeight = rectangleTexture->height();
     81     copySrcDesc.fFlags = kRenderTarget_GrSurfaceFlag;
     82     SkAutoTUnref<GrTexture> src(context->textureProvider()->createTexture(
     83             copySrcDesc, SkBudgeted::kYes, pixels.get(), 0));
     84 
     85     context->copySurface(rectangleTexture, src);
     86     test_read_pixels(reporter, context, rectangleTexture, pixels.get());
     87 }
     88 
     89 static void test_clear(skiatest::Reporter* reporter, GrContext* context,
     90                        GrTexture* rectangleTexture) {
     91     if (rectangleTexture->asRenderTarget()) {
     92         SkAutoTUnref<GrDrawContext> dc(context->drawContext(rectangleTexture->asRenderTarget()));
     93         if (!dc) {
     94             ERRORF(reporter, "Could not get GrDrawContext for rectangle texture.");
     95             return;
     96         }
     97 
     98         // Clear the whole thing.
     99         GrColor color0 = GrColorPackRGBA(0xA, 0xB, 0xC, 0xD);
    100         dc->clear(nullptr, color0, false);
    101 
    102         int w = rectangleTexture->width();
    103         int h = rectangleTexture->height();
    104         int pixelCnt = w * h;
    105         SkAutoTMalloc<uint32_t> expectedPixels(pixelCnt);
    106 
    107         // The clear color is a GrColor, our readback is to kRGBA_8888, which may be different.
    108         uint32_t expectedColor0 = 0;
    109         uint8_t* expectedBytes0 = SkTCast<uint8_t*>(&expectedColor0);
    110         expectedBytes0[0] = GrColorUnpackR(color0);
    111         expectedBytes0[1] = GrColorUnpackG(color0);
    112         expectedBytes0[2] = GrColorUnpackB(color0);
    113         expectedBytes0[3] = GrColorUnpackA(color0);
    114         for (int i = 0; i < rectangleTexture->width() * rectangleTexture->height(); ++i) {
    115             expectedPixels.get()[i] = expectedColor0;
    116         }
    117 
    118         // Clear the the top to a different color.
    119         GrColor color1 = GrColorPackRGBA(0x1, 0x2, 0x3, 0x4);
    120         SkIRect rect = SkIRect::MakeWH(w, h/2);
    121         dc->clear(&rect, color1, false);
    122 
    123         uint32_t expectedColor1 = 0;
    124         uint8_t* expectedBytes1 = SkTCast<uint8_t*>(&expectedColor1);
    125         expectedBytes1[0] = GrColorUnpackR(color1);
    126         expectedBytes1[1] = GrColorUnpackG(color1);
    127         expectedBytes1[2] = GrColorUnpackB(color1);
    128         expectedBytes1[3] = GrColorUnpackA(color1);
    129 
    130         for (int y = 0; y < h/2; ++y) {
    131             for (int x = 0; x < w; ++x) {
    132                 expectedPixels.get()[y * h + x] = expectedColor1;
    133             }
    134         }
    135 
    136         test_read_pixels(reporter, context, rectangleTexture, expectedPixels.get());
    137     }
    138 }
    139 
    140 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(RectangleTexture, reporter, context, glContext) {
    141     static const int kWidth = 13;
    142     static const int kHeight = 13;
    143 
    144     GrColor pixels[kWidth * kHeight];
    145     for (int y = 0; y < kHeight; ++y) {
    146         for (int x = 0; x < kWidth; ++x) {
    147             pixels[y * kWidth + x] = y * kWidth + x;
    148         }
    149     }
    150 
    151     for (int origin = 0; origin < 2; ++origin) {
    152         GrGLuint rectTexID = glContext->createTextureRectangle(kWidth, kHeight, GR_GL_RGBA,
    153                                                                GR_GL_RGBA, GR_GL_UNSIGNED_BYTE,
    154                                                                pixels);
    155 
    156         if (!rectTexID) {
    157             return;
    158         }
    159 
    160         // Let GrContext know that we messed with the GL context directly.
    161         context->resetContext();
    162 
    163         // Wrap the rectangle texture ID in a GrTexture
    164         GrGLTextureInfo rectangleInfo;
    165         rectangleInfo.fID = rectTexID;
    166         rectangleInfo.fTarget = GR_GL_TEXTURE_RECTANGLE;
    167 
    168         GrBackendTextureDesc rectangleDesc;
    169         rectangleDesc.fFlags = kRenderTarget_GrBackendTextureFlag;
    170         rectangleDesc.fConfig = kRGBA_8888_GrPixelConfig;
    171         rectangleDesc.fWidth = kWidth;
    172         rectangleDesc.fHeight = kHeight;
    173         rectangleDesc.fOrigin = origin ? kBottomLeft_GrSurfaceOrigin : kTopLeft_GrSurfaceOrigin;
    174         rectangleDesc.fTextureHandle = reinterpret_cast<GrBackendObject>(&rectangleInfo);
    175 
    176         GrColor refPixels[kWidth * kHeight];
    177         bool flipRef = rectangleDesc.fOrigin == kBottomLeft_GrSurfaceOrigin;
    178         for (int y = 0; y < kHeight; ++y) {
    179             for (int x = 0; x < kWidth; ++x) {
    180                 int y0 = flipRef ? kHeight - y - 1 : y;
    181                 refPixels[y * kWidth + x] = pixels[y0 * kWidth + x];
    182             }
    183         }
    184 
    185         SkAutoTUnref<GrTexture> rectangleTexture(
    186             context->textureProvider()->wrapBackendTexture(rectangleDesc));
    187         if (!rectangleTexture) {
    188             ERRORF(reporter, "Error wrapping rectangle texture in GrTexture.");
    189             GR_GL_CALL(glContext->gl(), DeleteTextures(1, &rectTexID));
    190             continue;
    191         }
    192 
    193         test_read_pixels(reporter, context, rectangleTexture, refPixels);
    194 
    195         test_copy_surface_src(reporter, context, rectangleTexture, refPixels);
    196 
    197         test_copy_surface_dst(reporter, context, rectangleTexture);
    198 
    199         test_write_pixels(reporter, context, rectangleTexture);
    200 
    201         test_clear(reporter, context, rectangleTexture);
    202 
    203         GR_GL_CALL(glContext->gl(), DeleteTextures(1, &rectTexID));
    204     }
    205 }
    206 
    207 #endif
    208