Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright 2016 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 <initializer_list>
      9 #include "Test.h"
     10 
     11 #if SK_SUPPORT_GPU
     12 #include "GrContext.h"
     13 #include "GrTexture.h"
     14 #include "GrTextureProvider.h"
     15 
     16 #include "SkUtils.h"
     17 
     18 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(CopySurface, reporter, context) {
     19     static const int kW = 10;
     20     static const int kH = 10;
     21     static const size_t kRowBytes = sizeof(uint32_t) * kW;
     22 
     23     GrSurfaceDesc baseDesc;
     24     baseDesc.fConfig = kRGBA_8888_GrPixelConfig;
     25     baseDesc.fWidth = kW;
     26     baseDesc.fHeight = kH;
     27 
     28     SkAutoTMalloc<uint32_t> srcPixels(kW * kH);
     29     for (int i = 0; i < kW * kH; ++i) {
     30         srcPixels.get()[i] = i;
     31     }
     32 
     33     SkAutoTMalloc<uint32_t> dstPixels(kW * kH);
     34     for (int i = 0; i < kW * kH; ++i) {
     35         dstPixels.get()[i] = ~i;
     36     }
     37 
     38     static const SkIRect kSrcRects[] {
     39         { 0,  0, kW  , kH  },
     40         {-1, -1, kW+1, kH+1},
     41         { 1,  1, kW-1, kH-1},
     42         { 5,  5, 6   , 6   },
     43     };
     44 
     45     static const SkIPoint kDstPoints[] {
     46         { 0   ,  0   },
     47         { 1   ,  1   },
     48         { kW/2,  kH/4},
     49         { kW-1,  kH-1},
     50         { kW  ,  kH  },
     51         { kW+1,  kH+2},
     52         {-1   , -1   },
     53     };
     54 
     55     SkAutoTMalloc<uint32_t> read(kW * kH);
     56 
     57     for (auto sOrigin : {kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin}) {
     58         for (auto dOrigin : {kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin}) {
     59             for (auto sFlags: {kRenderTarget_GrSurfaceFlag, kNone_GrSurfaceFlags}) {
     60                 for (auto dFlags: {kRenderTarget_GrSurfaceFlag, kNone_GrSurfaceFlags}) {
     61                     for (auto srcRect : kSrcRects) {
     62                         for (auto dstPoint : kDstPoints) {
     63                             GrSurfaceDesc srcDesc = baseDesc;
     64                             srcDesc.fOrigin = sOrigin;
     65                             srcDesc.fFlags = sFlags;
     66                             GrSurfaceDesc dstDesc = baseDesc;
     67                             dstDesc.fOrigin = dOrigin;
     68                             dstDesc.fFlags = dFlags;
     69 
     70                             SkAutoTUnref<GrTexture> src(
     71                                 context->textureProvider()->createTexture(srcDesc, SkBudgeted::kNo,
     72                                                                           srcPixels.get(),
     73                                                                           kRowBytes));
     74                             SkAutoTUnref<GrTexture> dst(
     75                                 context->textureProvider()->createTexture(dstDesc, SkBudgeted::kNo,
     76                                                                           dstPixels.get(),
     77                                                                           kRowBytes));
     78                             if (!src || !dst) {
     79                                 ERRORF(reporter,
     80                                        "Could not create surfaces for copy surface test.");
     81                                 continue;
     82                             }
     83 
     84                             bool result = context->copySurface(dst, src, srcRect, dstPoint);
     85 
     86                             bool expectedResult = true;
     87                             SkIPoint dstOffset = { dstPoint.fX - srcRect.fLeft,
     88                                                    dstPoint.fY - srcRect.fTop };
     89                             SkIRect copiedDstRect = SkIRect::MakeXYWH(dstPoint.fX,
     90                                                                       dstPoint.fY,
     91                                                                       srcRect.width(),
     92                                                                       srcRect.height());
     93 
     94                             SkIRect copiedSrcRect;
     95                             if (!copiedSrcRect.intersect(srcRect, SkIRect::MakeWH(kW, kH))) {
     96                                 expectedResult = false;
     97                             } else {
     98                                 // If the src rect was clipped, apply same clipping to each side of
     99                                 // copied dst rect.
    100                                 copiedDstRect.fLeft += copiedSrcRect.fLeft - srcRect.fLeft;
    101                                 copiedDstRect.fTop += copiedSrcRect.fTop - srcRect.fTop;
    102                                 copiedDstRect.fRight -= copiedSrcRect.fRight - srcRect.fRight;
    103                                 copiedDstRect.fBottom -= copiedSrcRect.fBottom - srcRect.fBottom;
    104                             }
    105                             if (copiedDstRect.isEmpty() ||
    106                                 !copiedDstRect.intersect(SkIRect::MakeWH(kW, kH))) {
    107                                 expectedResult = false;
    108                             }
    109                             // To make the copied src rect correct we would apply any dst clipping
    110                             // back to the src rect, but we don't use it again so don't bother.
    111                             if (expectedResult != result) {
    112                                 ERRORF(reporter, "Expected return value %d from copySurface, got "
    113                                        "%d.", expectedResult, result);
    114                                 continue;
    115                             }
    116 
    117                             if (!expectedResult || !result) {
    118                                 continue;
    119                             }
    120 
    121                             sk_memset32(read.get(), 0, kW * kH);
    122                             if (!dst->readPixels(0, 0, kW, kH, baseDesc.fConfig, read.get(),
    123                                                  kRowBytes)) {
    124                                 ERRORF(reporter, "Error calling readPixels");
    125                                 continue;
    126                             }
    127 
    128                             bool abort = false;
    129                             // Validate that pixels inside copiedDstRect received the correct value
    130                             // from src and that those outside were not modified.
    131                             for (int y = 0; y < kH && !abort; ++y) {
    132                                 for (int x = 0; x < kW; ++x) {
    133                                     uint32_t r = read.get()[y * kW + x];
    134                                     if (copiedDstRect.contains(x, y)) {
    135                                         int sx = x - dstOffset.fX;
    136                                         int sy = y - dstOffset.fY;
    137                                         uint32_t s = srcPixels.get()[sy * kW + sx];
    138                                         if (s != r) {
    139                                             ERRORF(reporter, "Expected dst %d,%d to contain "
    140                                                    "0x%08x copied from src location %d,%d. Got "
    141                                                    "0x%08x", x, y, s, sx, sy, r);
    142                                             abort = true;
    143                                             break;
    144                                         }
    145                                     } else {
    146                                         uint32_t d = dstPixels.get()[y * kW + x];
    147                                         if (d != r) {
    148                                             ERRORF(reporter, "Expected dst %d,%d to be unmodified ("
    149                                                    "0x%08x). Got 0x%08x", x, y, d, r);
    150                                             abort = true;
    151                                             break;
    152                                         }
    153                                     }
    154                                 }
    155                             }
    156                         }
    157                     }
    158                 }
    159             }
    160         }
    161     }
    162 }
    163 #endif
    164