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