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 "Test.h" 9 #if SK_SUPPORT_GPU 10 #include "gl/GrGLGpu.h" 11 #include "GrContext.h" 12 #include "SkSurface_Gpu.h" 13 #include "../include/gpu/gl/SkGLContext.h" 14 #include "../include/gpu/GrTypes.h" 15 #include "../include/private/SkTemplates.h" 16 17 class TestStorageAllocator { 18 public: 19 static GrTextureStorageAllocator::Result allocateTextureStorage(void* ctx, 20 GrBackendObject texture, unsigned width, unsigned height, GrPixelConfig config, 21 const void* srcData, GrSurfaceOrigin) { 22 TestStorageAllocator* allocator = static_cast<TestStorageAllocator*>(ctx); 23 if (!allocator->m_allowAllocation) 24 return GrTextureStorageAllocator::Result::kFailed; 25 SkAutoTMalloc<uint8_t> pixels(width * height * 4); 26 memset(pixels.get(), 0, width * height * 4); 27 28 GrGLuint id; 29 GrGLenum target = GR_GL_TEXTURE_2D; 30 GR_GL_CALL(allocator->m_gl, GenTextures(1, &id)); 31 GR_GL_CALL(allocator->m_gl, BindTexture(target, id)); 32 GR_GL_CALL(allocator->m_gl, TexParameteri(target, GR_GL_TEXTURE_MAG_FILTER, GR_GL_NEAREST)); 33 GR_GL_CALL(allocator->m_gl, TexParameteri(target, GR_GL_TEXTURE_MIN_FILTER, GR_GL_NEAREST)); 34 GR_GL_CALL(allocator->m_gl, TexParameteri(target, GR_GL_TEXTURE_WRAP_S, GR_GL_CLAMP_TO_EDGE)); 35 GR_GL_CALL(allocator->m_gl, TexParameteri(target, GR_GL_TEXTURE_WRAP_T, GR_GL_CLAMP_TO_EDGE)); 36 GR_GL_CALL(allocator->m_gl, TexImage2D(target, 0, GR_GL_RGBA, width, height, 0, GR_GL_RGBA, 37 GR_GL_UNSIGNED_BYTE, pixels.get())); 38 39 GrGLTextureInfo* info = reinterpret_cast<GrGLTextureInfo*>(texture); 40 info->fID = id; 41 info->fTarget = target; 42 allocator->m_mostRecentlyAllocatedStorage = id; 43 return GrTextureStorageAllocator::Result::kSucceededWithoutUpload; 44 } 45 static void deallocateTextureStorage(void* ctx, GrBackendObject texture) { 46 TestStorageAllocator* allocator = static_cast<TestStorageAllocator*>(ctx); 47 GrGLTextureInfo* info = reinterpret_cast<GrGLTextureInfo*>(texture); 48 GR_GL_CALL(allocator->m_gl, DeleteTextures(1, &(info->fID))); 49 } 50 51 GrGLuint m_mostRecentlyAllocatedStorage; 52 const GrGLInterface* m_gl; 53 bool m_allowAllocation; 54 }; 55 56 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(CustomTexture, reporter, context, glContext) { 57 static const int kWidth = 13; 58 static const int kHeight = 13; 59 60 const GrGLInterface* gl = glContext->gl(); 61 TestStorageAllocator allocator; 62 allocator.m_allowAllocation = true; 63 allocator.m_gl = gl; 64 GrTextureStorageAllocator grAllocator; 65 grAllocator.fAllocateTextureStorage = &TestStorageAllocator::allocateTextureStorage; 66 grAllocator.fDeallocateTextureStorage= &TestStorageAllocator::deallocateTextureStorage; 67 grAllocator.fCtx = &allocator; 68 69 SkAutoTUnref<SkSurface> surface(SkSurface_Gpu::NewRenderTarget( 70 context, SkBudgeted::kNo, SkImageInfo::MakeN32Premul(kWidth, kHeight), 0, 71 NULL, grAllocator)); 72 REPORTER_ASSERT(reporter, surface); 73 GrGLuint id = allocator.m_mostRecentlyAllocatedStorage; 74 75 SkAutoTUnref<SkImage> image(surface->newImageSnapshot()); 76 REPORTER_ASSERT(reporter, image->isTextureBacked()); 77 SkImageInfo imageInfo = SkImageInfo::MakeN32Premul(1,1); 78 GrColor dest = 0x11223344; 79 REPORTER_ASSERT(reporter, image->readPixels(imageInfo, &dest, 4 * kWidth, 0, 0)); 80 REPORTER_ASSERT(reporter, GrColorUnpackG(dest) == 0); 81 82 surface->getCanvas()->clear(SK_ColorGREEN); 83 SkAutoTUnref<SkImage> image2(surface->newImageSnapshot()); 84 REPORTER_ASSERT(reporter, image2->isTextureBacked()); 85 REPORTER_ASSERT(reporter, allocator.m_mostRecentlyAllocatedStorage != id); 86 87 REPORTER_ASSERT(reporter, image2->readPixels(imageInfo, &dest, 4 * kWidth, 0, 0)); 88 REPORTER_ASSERT(reporter, GrColorUnpackG(dest) == 255); 89 } 90 91 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(CustomTextureFailure, reporter, context, glContext) { 92 static const int kWidth = 13; 93 static const int kHeight = 13; 94 95 const GrGLInterface* gl = glContext->gl(); 96 TestStorageAllocator allocator; 97 allocator.m_allowAllocation = false; 98 allocator.m_gl = gl; 99 GrTextureStorageAllocator grAllocator; 100 grAllocator.fAllocateTextureStorage = &TestStorageAllocator::allocateTextureStorage; 101 grAllocator.fDeallocateTextureStorage= &TestStorageAllocator::deallocateTextureStorage; 102 grAllocator.fCtx = &allocator; 103 SkAutoTUnref<SkSurface> surface(SkSurface_Gpu::NewRenderTarget( 104 context, SkBudgeted::kNo, SkImageInfo::MakeN32Premul(kWidth, kHeight), 0, 105 NULL, grAllocator)); 106 REPORTER_ASSERT(reporter, !surface); 107 } 108 109 #endif 110