Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright 2014 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 /*
      9  * This is a straightforward test of floating point textures, which are
     10  * supported on some platforms.  As of right now, this test only supports
     11  * 32 bit floating point textures, and indeed floating point test values
     12  * have been selected to require 32 bits of precision and full IEEE conformance
     13  */
     14 
     15 #include <float.h>
     16 #include "Test.h"
     17 #if SK_SUPPORT_GPU
     18 #include "GrContext.h"
     19 #include "GrTexture.h"
     20 #include "GrContextFactory.h"
     21 
     22 #include "SkGpuDevice.h"
     23 #include "SkHalf.h"
     24 
     25 static const int DEV_W = 100, DEV_H = 100;
     26 static const int FP_CONTROL_ARRAY_SIZE = DEV_W * DEV_H * 4/*RGBA*/;
     27 static const float kMaxIntegerRepresentableInSPFloatingPoint = 16777216;  // 2 ^ 24
     28 
     29 static const SkIRect DEV_RECT = SkIRect::MakeWH(DEV_W, DEV_H);
     30 
     31 DEF_GPUTEST(FloatingPointTextureTest, reporter, factory) {
     32     SkTDArray<float> controlPixelData, readBuffer;
     33     controlPixelData.setCount(FP_CONTROL_ARRAY_SIZE);
     34     readBuffer.setCount(FP_CONTROL_ARRAY_SIZE);
     35 
     36     for (int i = 0; i < FP_CONTROL_ARRAY_SIZE; i += 4) {
     37         controlPixelData[i + 0] = FLT_MIN;
     38         controlPixelData[i + 1] = FLT_MAX;
     39         controlPixelData[i + 2] = FLT_EPSILON;
     40         controlPixelData[i + 3] = kMaxIntegerRepresentableInSPFloatingPoint;
     41     }
     42 
     43     for (int origin = 0; origin < 2; ++origin) {
     44         for (int glCtxType = 0; glCtxType < GrContextFactory::kGLContextTypeCnt; ++glCtxType) {
     45             GrSurfaceDesc desc;
     46             desc.fFlags  = kRenderTarget_GrSurfaceFlag;
     47             desc.fWidth  = DEV_W;
     48             desc.fHeight = DEV_H;
     49             desc.fConfig = kRGBA_float_GrPixelConfig;
     50             desc.fOrigin = 0 == origin ?
     51                 kTopLeft_GrSurfaceOrigin : kBottomLeft_GrSurfaceOrigin;
     52 
     53             GrContextFactory::GLContextType type =
     54                 static_cast<GrContextFactory::GLContextType>(glCtxType);
     55             if (!GrContextFactory::IsRenderingGLContext(type)) {
     56                 continue;
     57             }
     58             GrContext* context = factory->get(type);
     59             if (NULL == context){
     60                 continue;
     61             }
     62 
     63             SkAutoTUnref<GrTexture> fpTexture(context->textureProvider()->createTexture(
     64                 desc, false, controlPixelData.begin(), 0));
     65             // Floating point textures are NOT supported everywhere
     66             if (NULL == fpTexture) {
     67                 continue;
     68             }
     69             fpTexture->readPixels(0, 0, DEV_W, DEV_H, desc.fConfig, readBuffer.begin(), 0);
     70             REPORTER_ASSERT(reporter,
     71                     0 == memcmp(readBuffer.begin(), controlPixelData.begin(), readBuffer.bytes()));
     72         }
     73     }
     74 }
     75 
     76 static const int HALF_CONTROL_ARRAY_SIZE = DEV_W * DEV_H * 1 /*alpha-only*/;
     77 
     78 DEF_GPUTEST(HalfFloatTextureTest, reporter, factory) {
     79     SkTDArray<SkHalf> controlPixelData, readBuffer;
     80     controlPixelData.setCount(HALF_CONTROL_ARRAY_SIZE);
     81     readBuffer.setCount(HALF_CONTROL_ARRAY_SIZE);
     82 
     83     for (int i = 0; i < HALF_CONTROL_ARRAY_SIZE; i += 4) {
     84         controlPixelData[i + 0] = SK_HalfMin;
     85         controlPixelData[i + 1] = SK_HalfMax;
     86         controlPixelData[i + 2] = SK_HalfEpsilon;
     87         controlPixelData[i + 3] = 0x6800;   // 2^11
     88     }
     89 
     90     for (int origin = 0; origin < 2; ++origin) {
     91         for (int glCtxType = 0; glCtxType < GrContextFactory::kGLContextTypeCnt; ++glCtxType) {
     92             GrSurfaceDesc desc;
     93             desc.fFlags  = kRenderTarget_GrSurfaceFlag;
     94             desc.fWidth  = DEV_W;
     95             desc.fHeight = DEV_H;
     96             desc.fConfig = kAlpha_half_GrPixelConfig;
     97             desc.fOrigin = 0 == origin ?
     98                 kTopLeft_GrSurfaceOrigin : kBottomLeft_GrSurfaceOrigin;
     99 
    100             GrContextFactory::GLContextType type =
    101                 static_cast<GrContextFactory::GLContextType>(glCtxType);
    102             if (!GrContextFactory::IsRenderingGLContext(type)) {
    103                 continue;
    104             }
    105             GrContext* context = factory->get(type);
    106             if (NULL == context){
    107                 continue;
    108             }
    109 
    110             SkAutoTUnref<GrTexture> fpTexture(context->textureProvider()->createTexture(
    111                 desc, false, controlPixelData.begin(), 0));
    112             // 16-bit floating point textures are NOT supported everywhere
    113             if (NULL == fpTexture) {
    114                 continue;
    115             }
    116             fpTexture->readPixels(0, 0, DEV_W, DEV_H, desc.fConfig, readBuffer.begin(), 0);
    117             REPORTER_ASSERT(reporter,
    118                     0 == memcmp(readBuffer.begin(), controlPixelData.begin(), readBuffer.bytes()));
    119         }
    120     }
    121 }
    122 
    123 #endif
    124