1e179a9167f71dfc41668b05d40082aae76367fa6bsalomon 2e179a9167f71dfc41668b05d40082aae76367fa6bsalomon/* 3e179a9167f71dfc41668b05d40082aae76367fa6bsalomon * Copyright 2016 Google Inc. 4e179a9167f71dfc41668b05d40082aae76367fa6bsalomon * 5e179a9167f71dfc41668b05d40082aae76367fa6bsalomon * Use of this source code is governed by a BSD-style license that can be 6e179a9167f71dfc41668b05d40082aae76367fa6bsalomon * found in the LICENSE file. 7e179a9167f71dfc41668b05d40082aae76367fa6bsalomon */ 8e179a9167f71dfc41668b05d40082aae76367fa6bsalomon 9e179a9167f71dfc41668b05d40082aae76367fa6bsalomon// This test only works with the GPU backend. 10e179a9167f71dfc41668b05d40082aae76367fa6bsalomon 11e179a9167f71dfc41668b05d40082aae76367fa6bsalomon#include "gm.h" 12e179a9167f71dfc41668b05d40082aae76367fa6bsalomon 13e179a9167f71dfc41668b05d40082aae76367fa6bsalomon#if SK_SUPPORT_GPU 14e179a9167f71dfc41668b05d40082aae76367fa6bsalomon 15e179a9167f71dfc41668b05d40082aae76367fa6bsalomon#include "GrContext.h" 16e179a9167f71dfc41668b05d40082aae76367fa6bsalomon#include "GrTest.h" 17e179a9167f71dfc41668b05d40082aae76367fa6bsalomon#include "SkBitmap.h" 18e179a9167f71dfc41668b05d40082aae76367fa6bsalomon#include "SkGradientShader.h" 19e179a9167f71dfc41668b05d40082aae76367fa6bsalomon#include "SkImage.h" 20e179a9167f71dfc41668b05d40082aae76367fa6bsalomon 21e179a9167f71dfc41668b05d40082aae76367fa6bsalomonnamespace skiagm { 22e179a9167f71dfc41668b05d40082aae76367fa6bsalomonclass RectangleTexture : public GM { 23e179a9167f71dfc41668b05d40082aae76367fa6bsalomonpublic: 24e179a9167f71dfc41668b05d40082aae76367fa6bsalomon RectangleTexture() { 25e179a9167f71dfc41668b05d40082aae76367fa6bsalomon this->setBGColor(0xFFFFFFFF); 26e179a9167f71dfc41668b05d40082aae76367fa6bsalomon } 27e179a9167f71dfc41668b05d40082aae76367fa6bsalomon 28e179a9167f71dfc41668b05d40082aae76367fa6bsalomonprotected: 29e179a9167f71dfc41668b05d40082aae76367fa6bsalomon SkString onShortName() override { 30e179a9167f71dfc41668b05d40082aae76367fa6bsalomon return SkString("rectangle_texture"); 31e179a9167f71dfc41668b05d40082aae76367fa6bsalomon } 32e179a9167f71dfc41668b05d40082aae76367fa6bsalomon 33e179a9167f71dfc41668b05d40082aae76367fa6bsalomon SkISize onISize() override { 34e179a9167f71dfc41668b05d40082aae76367fa6bsalomon return SkISize::Make(1035, 240); 35e179a9167f71dfc41668b05d40082aae76367fa6bsalomon } 36e179a9167f71dfc41668b05d40082aae76367fa6bsalomon 37e179a9167f71dfc41668b05d40082aae76367fa6bsalomon void fillPixels(int width, int height, void *pixels) { 38e179a9167f71dfc41668b05d40082aae76367fa6bsalomon SkBitmap bmp; 39e179a9167f71dfc41668b05d40082aae76367fa6bsalomon bmp.setInfo(SkImageInfo::MakeN32(width, height, kOpaque_SkAlphaType), width * 4); 40e179a9167f71dfc41668b05d40082aae76367fa6bsalomon bmp.setPixels(pixels); 41e179a9167f71dfc41668b05d40082aae76367fa6bsalomon SkPaint paint; 42e179a9167f71dfc41668b05d40082aae76367fa6bsalomon SkCanvas canvas(bmp); 43e179a9167f71dfc41668b05d40082aae76367fa6bsalomon SkPoint pts[] = { {0, 0}, {0, SkIntToScalar(height)} }; 44e179a9167f71dfc41668b05d40082aae76367fa6bsalomon SkColor colors0[] = { 0xFF1060B0 , 0xFF102030 }; 45e179a9167f71dfc41668b05d40082aae76367fa6bsalomon paint.setShader(SkGradientShader::CreateLinear(pts, colors0, nullptr, 2, 46e179a9167f71dfc41668b05d40082aae76367fa6bsalomon SkShader::kClamp_TileMode))->unref(); 47e179a9167f71dfc41668b05d40082aae76367fa6bsalomon canvas.drawPaint(paint); 48e179a9167f71dfc41668b05d40082aae76367fa6bsalomon 49e179a9167f71dfc41668b05d40082aae76367fa6bsalomon SkColor colors1[] = { 0xFFA07010 , 0xFFA02080 }; 50e179a9167f71dfc41668b05d40082aae76367fa6bsalomon paint.setAntiAlias(true); 51e179a9167f71dfc41668b05d40082aae76367fa6bsalomon paint.setShader(SkGradientShader::CreateLinear(pts, colors1, nullptr, 2, 52e179a9167f71dfc41668b05d40082aae76367fa6bsalomon SkShader::kClamp_TileMode))->unref(); 53e179a9167f71dfc41668b05d40082aae76367fa6bsalomon canvas.drawCircle(SkIntToScalar(width) / 2, SkIntToScalar(height) / 2, 54e179a9167f71dfc41668b05d40082aae76367fa6bsalomon SkIntToScalar(width + height) / 5, paint); 55e179a9167f71dfc41668b05d40082aae76367fa6bsalomon } 56e179a9167f71dfc41668b05d40082aae76367fa6bsalomon 57e179a9167f71dfc41668b05d40082aae76367fa6bsalomon SkImage* createRectangleTextureImg(GrContext* context, int width, int height, void* pixels) { 58e179a9167f71dfc41668b05d40082aae76367fa6bsalomon if (!context) { 59e179a9167f71dfc41668b05d40082aae76367fa6bsalomon return nullptr; 60e179a9167f71dfc41668b05d40082aae76367fa6bsalomon } 61e179a9167f71dfc41668b05d40082aae76367fa6bsalomon GrGpu* gpu = context->getGpu(); 62e179a9167f71dfc41668b05d40082aae76367fa6bsalomon if (!gpu) { 63e179a9167f71dfc41668b05d40082aae76367fa6bsalomon return nullptr; 64e179a9167f71dfc41668b05d40082aae76367fa6bsalomon } 65e179a9167f71dfc41668b05d40082aae76367fa6bsalomon const GrGLContext* glCtx = gpu->glContextForTesting(); 66e179a9167f71dfc41668b05d40082aae76367fa6bsalomon if (!glCtx) { 67e179a9167f71dfc41668b05d40082aae76367fa6bsalomon return nullptr; 68e179a9167f71dfc41668b05d40082aae76367fa6bsalomon } 69e179a9167f71dfc41668b05d40082aae76367fa6bsalomon 70e179a9167f71dfc41668b05d40082aae76367fa6bsalomon if (!(kGL_GrGLStandard == glCtx->standard() && glCtx->version() >= GR_GL_VER(3, 1)) && 71e179a9167f71dfc41668b05d40082aae76367fa6bsalomon !glCtx->hasExtension("GL_ARB_texture_rectangle")) { 72e179a9167f71dfc41668b05d40082aae76367fa6bsalomon return nullptr; 73e179a9167f71dfc41668b05d40082aae76367fa6bsalomon } 74e179a9167f71dfc41668b05d40082aae76367fa6bsalomon 75e179a9167f71dfc41668b05d40082aae76367fa6bsalomon // We will always create the GL texture as GL_RGBA, however the pixels uploaded may be 76e179a9167f71dfc41668b05d40082aae76367fa6bsalomon // be RGBA or BGRA, depending on how SkPMColor was compiled. 77e179a9167f71dfc41668b05d40082aae76367fa6bsalomon GrGLenum format; 78e179a9167f71dfc41668b05d40082aae76367fa6bsalomon if (kSkia8888_GrPixelConfig == kBGRA_8888_GrPixelConfig) { 79e179a9167f71dfc41668b05d40082aae76367fa6bsalomon format = GR_GL_BGRA; 80e179a9167f71dfc41668b05d40082aae76367fa6bsalomon } else { 81e179a9167f71dfc41668b05d40082aae76367fa6bsalomon SkASSERT(kSkia8888_GrPixelConfig == kRGBA_8888_GrPixelConfig); 82e179a9167f71dfc41668b05d40082aae76367fa6bsalomon format = GR_GL_RGBA; 83e179a9167f71dfc41668b05d40082aae76367fa6bsalomon } 84e179a9167f71dfc41668b05d40082aae76367fa6bsalomon 85e179a9167f71dfc41668b05d40082aae76367fa6bsalomon const GrGLInterface* gl = glCtx->interface(); 86e179a9167f71dfc41668b05d40082aae76367fa6bsalomon// Useful for debugging whether errors result from use of RECTANGLE 87e179a9167f71dfc41668b05d40082aae76367fa6bsalomon// #define TARGET GR_GL_TEXTURE_2D 88e179a9167f71dfc41668b05d40082aae76367fa6bsalomon#define TARGET GR_GL_TEXTURE_RECTANGLE 89e179a9167f71dfc41668b05d40082aae76367fa6bsalomon GrGLuint id; 90e179a9167f71dfc41668b05d40082aae76367fa6bsalomon GR_GL_CALL(gl, GenTextures(1, &id)); 91e179a9167f71dfc41668b05d40082aae76367fa6bsalomon GR_GL_CALL(gl, BindTexture(TARGET, id)); 92e179a9167f71dfc41668b05d40082aae76367fa6bsalomon GR_GL_CALL(gl, TexParameteri(TARGET, GR_GL_TEXTURE_MAG_FILTER, 93e179a9167f71dfc41668b05d40082aae76367fa6bsalomon GR_GL_NEAREST)); 94e179a9167f71dfc41668b05d40082aae76367fa6bsalomon GR_GL_CALL(gl, TexParameteri(TARGET, GR_GL_TEXTURE_MIN_FILTER, 95e179a9167f71dfc41668b05d40082aae76367fa6bsalomon GR_GL_NEAREST)); 96e179a9167f71dfc41668b05d40082aae76367fa6bsalomon GR_GL_CALL(gl, TexParameteri(TARGET, GR_GL_TEXTURE_WRAP_S, 97e179a9167f71dfc41668b05d40082aae76367fa6bsalomon GR_GL_CLAMP_TO_EDGE)); 98e179a9167f71dfc41668b05d40082aae76367fa6bsalomon GR_GL_CALL(gl, TexParameteri(TARGET, GR_GL_TEXTURE_WRAP_T, 99e179a9167f71dfc41668b05d40082aae76367fa6bsalomon GR_GL_CLAMP_TO_EDGE)); 100e179a9167f71dfc41668b05d40082aae76367fa6bsalomon GR_GL_CALL(gl, TexImage2D(TARGET, 0, GR_GL_RGBA, width, height, 0, 101e179a9167f71dfc41668b05d40082aae76367fa6bsalomon format, GR_GL_UNSIGNED_BYTE, pixels)); 102e179a9167f71dfc41668b05d40082aae76367fa6bsalomon 103e179a9167f71dfc41668b05d40082aae76367fa6bsalomon 104e179a9167f71dfc41668b05d40082aae76367fa6bsalomon context->resetContext(); 105e179a9167f71dfc41668b05d40082aae76367fa6bsalomon GrGLTextureInfo info; 106e179a9167f71dfc41668b05d40082aae76367fa6bsalomon info.fID = id; 107e179a9167f71dfc41668b05d40082aae76367fa6bsalomon info.fTarget = TARGET; 108e179a9167f71dfc41668b05d40082aae76367fa6bsalomon GrBackendTextureDesc desc; 109e179a9167f71dfc41668b05d40082aae76367fa6bsalomon desc.fConfig = kRGBA_8888_GrPixelConfig; 110e179a9167f71dfc41668b05d40082aae76367fa6bsalomon desc.fWidth = width; 111e179a9167f71dfc41668b05d40082aae76367fa6bsalomon desc.fHeight = height; 112e179a9167f71dfc41668b05d40082aae76367fa6bsalomon desc.fOrigin = kTopLeft_GrSurfaceOrigin; 113e179a9167f71dfc41668b05d40082aae76367fa6bsalomon desc.fTextureHandle = reinterpret_cast<GrBackendObject>(&info); 114e179a9167f71dfc41668b05d40082aae76367fa6bsalomon if (SkImage* image = SkImage::NewFromAdoptedTexture(context, desc)) { 115e179a9167f71dfc41668b05d40082aae76367fa6bsalomon return image; 116e179a9167f71dfc41668b05d40082aae76367fa6bsalomon } 117e179a9167f71dfc41668b05d40082aae76367fa6bsalomon GR_GL_CALL(gl, DeleteTextures(1, &id)); 118e179a9167f71dfc41668b05d40082aae76367fa6bsalomon return nullptr; 119e179a9167f71dfc41668b05d40082aae76367fa6bsalomon } 120e179a9167f71dfc41668b05d40082aae76367fa6bsalomon 121e179a9167f71dfc41668b05d40082aae76367fa6bsalomon void onDraw(SkCanvas* canvas) override { 122e179a9167f71dfc41668b05d40082aae76367fa6bsalomon GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget(); 123e179a9167f71dfc41668b05d40082aae76367fa6bsalomon GrContext* context; 124e179a9167f71dfc41668b05d40082aae76367fa6bsalomon if (!rt || !(context = rt->getContext())) { 125e179a9167f71dfc41668b05d40082aae76367fa6bsalomon skiagm::GM::DrawGpuOnlyMessage(canvas); 126e179a9167f71dfc41668b05d40082aae76367fa6bsalomon return; 127e179a9167f71dfc41668b05d40082aae76367fa6bsalomon } 128e179a9167f71dfc41668b05d40082aae76367fa6bsalomon 129e179a9167f71dfc41668b05d40082aae76367fa6bsalomon static const int kWidth = 50; 130e179a9167f71dfc41668b05d40082aae76367fa6bsalomon static const int kHeight = 50; 131e179a9167f71dfc41668b05d40082aae76367fa6bsalomon static const SkScalar kPad = 5.f; 132e179a9167f71dfc41668b05d40082aae76367fa6bsalomon 133e179a9167f71dfc41668b05d40082aae76367fa6bsalomon SkPMColor pixels[kWidth * kHeight]; 134e179a9167f71dfc41668b05d40082aae76367fa6bsalomon this->fillPixels(kWidth, kHeight, pixels); 135e179a9167f71dfc41668b05d40082aae76367fa6bsalomon SkAutoTUnref<SkImage> rectImg(this->createRectangleTextureImg(context, kWidth, kHeight, 136e179a9167f71dfc41668b05d40082aae76367fa6bsalomon pixels)); 137e179a9167f71dfc41668b05d40082aae76367fa6bsalomon 138e179a9167f71dfc41668b05d40082aae76367fa6bsalomon if (!rectImg) { 139e179a9167f71dfc41668b05d40082aae76367fa6bsalomon SkPaint paint; 140e179a9167f71dfc41668b05d40082aae76367fa6bsalomon paint.setAntiAlias(true); 141e179a9167f71dfc41668b05d40082aae76367fa6bsalomon static const char* kMsg = "Could not create rectangle texture image."; 142e179a9167f71dfc41668b05d40082aae76367fa6bsalomon canvas->drawText(kMsg, strlen(kMsg), 10, 100, paint); 143e179a9167f71dfc41668b05d40082aae76367fa6bsalomon return; 144e179a9167f71dfc41668b05d40082aae76367fa6bsalomon } 145e179a9167f71dfc41668b05d40082aae76367fa6bsalomon 146e179a9167f71dfc41668b05d40082aae76367fa6bsalomon static const SkFilterQuality kQualities[] = { 147e179a9167f71dfc41668b05d40082aae76367fa6bsalomon kNone_SkFilterQuality, 148e179a9167f71dfc41668b05d40082aae76367fa6bsalomon kLow_SkFilterQuality, 149e179a9167f71dfc41668b05d40082aae76367fa6bsalomon kMedium_SkFilterQuality, 150e179a9167f71dfc41668b05d40082aae76367fa6bsalomon kHigh_SkFilterQuality, 151e179a9167f71dfc41668b05d40082aae76367fa6bsalomon }; 152e179a9167f71dfc41668b05d40082aae76367fa6bsalomon 153e179a9167f71dfc41668b05d40082aae76367fa6bsalomon static const SkScalar kScales[] = { 1.0f, 1.2f, 0.75f }; 154e179a9167f71dfc41668b05d40082aae76367fa6bsalomon 155e179a9167f71dfc41668b05d40082aae76367fa6bsalomon canvas->translate(kPad, kPad); 156e179a9167f71dfc41668b05d40082aae76367fa6bsalomon for (auto s : kScales) { 157e179a9167f71dfc41668b05d40082aae76367fa6bsalomon canvas->save(); 158e179a9167f71dfc41668b05d40082aae76367fa6bsalomon canvas->scale(s, s); 159e179a9167f71dfc41668b05d40082aae76367fa6bsalomon for (auto q : kQualities) { 160e179a9167f71dfc41668b05d40082aae76367fa6bsalomon SkPaint plainPaint; 161e179a9167f71dfc41668b05d40082aae76367fa6bsalomon plainPaint.setFilterQuality(q); 162e179a9167f71dfc41668b05d40082aae76367fa6bsalomon canvas->drawImage(rectImg, 0, 0, &plainPaint); 163e179a9167f71dfc41668b05d40082aae76367fa6bsalomon canvas->translate(kWidth + kPad, 0); 164e179a9167f71dfc41668b05d40082aae76367fa6bsalomon 165e179a9167f71dfc41668b05d40082aae76367fa6bsalomon SkPaint clampPaint; 166e179a9167f71dfc41668b05d40082aae76367fa6bsalomon clampPaint.setFilterQuality(q); 167e179a9167f71dfc41668b05d40082aae76367fa6bsalomon clampPaint.setShader(rectImg->newShader(SkShader::kClamp_TileMode, 168e179a9167f71dfc41668b05d40082aae76367fa6bsalomon SkShader::kClamp_TileMode))->unref(); 169e179a9167f71dfc41668b05d40082aae76367fa6bsalomon canvas->drawRect(SkRect::MakeWH(1.5f * kWidth, 1.5f * kHeight), clampPaint); 170e179a9167f71dfc41668b05d40082aae76367fa6bsalomon canvas->translate(kWidth * 1.5f + kPad, 0); 171e179a9167f71dfc41668b05d40082aae76367fa6bsalomon 172e179a9167f71dfc41668b05d40082aae76367fa6bsalomon SkPaint repeatPaint; 173e179a9167f71dfc41668b05d40082aae76367fa6bsalomon repeatPaint.setFilterQuality(q); 174e179a9167f71dfc41668b05d40082aae76367fa6bsalomon repeatPaint.setShader(rectImg->newShader(SkShader::kRepeat_TileMode, 175e179a9167f71dfc41668b05d40082aae76367fa6bsalomon SkShader::kMirror_TileMode))->unref(); 176e179a9167f71dfc41668b05d40082aae76367fa6bsalomon canvas->drawRect(SkRect::MakeWH(1.5f * kWidth, 1.5f * kHeight), repeatPaint); 177e179a9167f71dfc41668b05d40082aae76367fa6bsalomon canvas->translate(1.5f * kWidth + kPad, 0); 178e179a9167f71dfc41668b05d40082aae76367fa6bsalomon } 179e179a9167f71dfc41668b05d40082aae76367fa6bsalomon canvas->restore(); 180e179a9167f71dfc41668b05d40082aae76367fa6bsalomon canvas->translate(0, kPad + 1.5f * kHeight * s); 181e179a9167f71dfc41668b05d40082aae76367fa6bsalomon } 182e179a9167f71dfc41668b05d40082aae76367fa6bsalomon } 183e179a9167f71dfc41668b05d40082aae76367fa6bsalomon 184e179a9167f71dfc41668b05d40082aae76367fa6bsalomonprivate: 185e179a9167f71dfc41668b05d40082aae76367fa6bsalomon typedef GM INHERITED; 186e179a9167f71dfc41668b05d40082aae76367fa6bsalomon}; 187e179a9167f71dfc41668b05d40082aae76367fa6bsalomon 188e179a9167f71dfc41668b05d40082aae76367fa6bsalomonDEF_GM(return new RectangleTexture;) 189e179a9167f71dfc41668b05d40082aae76367fa6bsalomon} 190e179a9167f71dfc41668b05d40082aae76367fa6bsalomon 191e179a9167f71dfc41668b05d40082aae76367fa6bsalomon#endif 192