RectangleTextureTest.cpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /*
  2. * Copyright 2015 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. #include "tests/Test.h"
  8. #include "tests/TestUtils.h"
  9. #include "include/gpu/GrContext.h"
  10. #include "src/gpu/GrClip.h"
  11. #include "src/gpu/GrContextPriv.h"
  12. #include "src/gpu/GrProxyProvider.h"
  13. #include "src/gpu/GrRenderTargetContext.h"
  14. #include "src/gpu/GrSurfaceContextPriv.h"
  15. #include "src/gpu/GrSurfacePriv.h"
  16. #include "src/gpu/GrTexturePriv.h"
  17. #include "src/gpu/SkGr.h"
  18. #include "src/gpu/gl/GrGLGpu.h"
  19. #include "src/gpu/gl/GrGLUtil.h"
  20. #include "tools/gpu/ProxyUtils.h"
  21. #include "tools/gpu/gl/GLTestContext.h"
  22. // skbug.com/5932
  23. static void test_basic_draw_as_src(skiatest::Reporter* reporter, GrContext* context,
  24. sk_sp<GrTextureProxy> rectProxy, GrColorType colorType,
  25. uint32_t expectedPixelValues[]) {
  26. sk_sp<GrRenderTargetContext> rtContext(context->priv().makeDeferredRenderTargetContext(
  27. SkBackingFit::kExact, rectProxy->width(), rectProxy->height(), colorType, nullptr));
  28. for (auto filter : {GrSamplerState::Filter::kNearest,
  29. GrSamplerState::Filter::kBilerp,
  30. GrSamplerState::Filter::kMipMap}) {
  31. rtContext->clear(nullptr, SkPMColor4f::FromBytes_RGBA(0xDDCCBBAA),
  32. GrRenderTargetContext::CanClearFullscreen::kYes);
  33. auto fp = GrSimpleTextureEffect::Make(rectProxy, SkMatrix::I(), filter);
  34. GrPaint paint;
  35. paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
  36. paint.addColorFragmentProcessor(std::move(fp));
  37. rtContext->drawPaint(GrNoClip(), std::move(paint), SkMatrix::I());
  38. test_read_pixels(reporter, rtContext.get(), expectedPixelValues,
  39. "RectangleTexture-basic-draw");
  40. }
  41. }
  42. static void test_clear(skiatest::Reporter* reporter, GrSurfaceContext* rectContext) {
  43. if (GrRenderTargetContext* rtc = rectContext->asRenderTargetContext()) {
  44. // Clear the whole thing.
  45. GrColor color0 = GrColorPackRGBA(0xA, 0xB, 0xC, 0xD);
  46. rtc->clear(nullptr, SkPMColor4f::FromBytes_RGBA(color0),
  47. GrRenderTargetContext::CanClearFullscreen::kNo);
  48. int w = rtc->width();
  49. int h = rtc->height();
  50. int pixelCnt = w * h;
  51. SkAutoTMalloc<uint32_t> expectedPixels(pixelCnt);
  52. // The clear color is a GrColor, our readback is to kRGBA_8888, which may be different.
  53. uint32_t expectedColor0 = 0;
  54. uint8_t* expectedBytes0 = reinterpret_cast<uint8_t*>(&expectedColor0);
  55. expectedBytes0[0] = GrColorUnpackR(color0);
  56. expectedBytes0[1] = GrColorUnpackG(color0);
  57. expectedBytes0[2] = GrColorUnpackB(color0);
  58. expectedBytes0[3] = GrColorUnpackA(color0);
  59. for (int i = 0; i < rtc->width() * rtc->height(); ++i) {
  60. expectedPixels.get()[i] = expectedColor0;
  61. }
  62. // Clear the the top to a different color.
  63. GrColor color1 = GrColorPackRGBA(0x1, 0x2, 0x3, 0x4);
  64. SkIRect rect = SkIRect::MakeWH(w, h/2);
  65. rtc->clear(&rect, SkPMColor4f::FromBytes_RGBA(color1),
  66. GrRenderTargetContext::CanClearFullscreen::kNo);
  67. uint32_t expectedColor1 = 0;
  68. uint8_t* expectedBytes1 = reinterpret_cast<uint8_t*>(&expectedColor1);
  69. expectedBytes1[0] = GrColorUnpackR(color1);
  70. expectedBytes1[1] = GrColorUnpackG(color1);
  71. expectedBytes1[2] = GrColorUnpackB(color1);
  72. expectedBytes1[3] = GrColorUnpackA(color1);
  73. for (int y = 0; y < h/2; ++y) {
  74. for (int x = 0; x < w; ++x) {
  75. expectedPixels.get()[y * h + x] = expectedColor1;
  76. }
  77. }
  78. test_read_pixels(reporter, rtc, expectedPixels.get(), "RectangleTexture-clear");
  79. }
  80. }
  81. static void test_copy_to_surface(skiatest::Reporter* reporter,
  82. GrContext* context,
  83. GrSurfaceContext* dstContext,
  84. const char* testName) {
  85. int pixelCnt = dstContext->width() * dstContext->height();
  86. SkAutoTMalloc<uint32_t> pixels(pixelCnt);
  87. for (int y = 0; y < dstContext->width(); ++y) {
  88. for (int x = 0; x < dstContext->height(); ++x) {
  89. pixels.get()[y * dstContext->width() + x] =
  90. SkColorToPremulGrColor(SkColorSetARGB(2*y, y, x, x * y));
  91. }
  92. }
  93. for (auto renderable : {GrRenderable::kNo, GrRenderable::kYes}) {
  94. auto origin = dstContext->asSurfaceProxy()->origin();
  95. auto src = sk_gpu_test::MakeTextureProxyFromData(
  96. context, renderable, dstContext->width(), dstContext->height(),
  97. kRGBA_8888_SkColorType, kPremul_SkAlphaType, origin, pixels.get(), 0);
  98. // If this assert ever fails we can add a fallback to do copy as draw, but until then we can
  99. // be more restrictive.
  100. SkAssertResult(dstContext->testCopy(src.get()));
  101. test_read_pixels(reporter, dstContext, pixels.get(), testName);
  102. }
  103. }
  104. DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(RectangleTexture, reporter, ctxInfo) {
  105. GrContext* context = ctxInfo.grContext();
  106. GrProxyProvider* proxyProvider = context->priv().proxyProvider();
  107. sk_gpu_test::GLTestContext* glContext = ctxInfo.glContext();
  108. static const int kWidth = 16;
  109. static const int kHeight = 16;
  110. GrColor pixels[kWidth * kHeight];
  111. for (int y = 0; y < kHeight; ++y) {
  112. for (int x = 0; x < kWidth; ++x) {
  113. pixels[y * kWidth + x] = y * kWidth + x;
  114. }
  115. }
  116. for (auto origin : { kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin }) {
  117. bool useBLOrigin = kBottomLeft_GrSurfaceOrigin == origin;
  118. GrGLuint rectTexID = glContext->createTextureRectangle(kWidth, kHeight, GR_GL_RGBA,
  119. GR_GL_RGBA, GR_GL_UNSIGNED_BYTE,
  120. pixels);
  121. if (!rectTexID) {
  122. return;
  123. }
  124. // Let GrContext know that we messed with the GL context directly.
  125. context->resetContext();
  126. // Wrap the rectangle texture ID in a GrTexture
  127. GrGLTextureInfo rectangleInfo;
  128. rectangleInfo.fID = rectTexID;
  129. rectangleInfo.fTarget = GR_GL_TEXTURE_RECTANGLE;
  130. rectangleInfo.fFormat = GR_GL_RGBA8;
  131. GrBackendTexture rectangleTex(kWidth, kHeight, GrMipMapped::kNo, rectangleInfo);
  132. rectangleTex.setPixelConfig(kRGBA_8888_GrPixelConfig);
  133. GrColor refPixels[kWidth * kHeight];
  134. for (int y = 0; y < kHeight; ++y) {
  135. for (int x = 0; x < kWidth; ++x) {
  136. int y0 = useBLOrigin ? kHeight - y - 1 : y;
  137. refPixels[y * kWidth + x] = pixels[y0 * kWidth + x];
  138. }
  139. }
  140. sk_sp<GrTextureProxy> rectProxy = proxyProvider->wrapBackendTexture(
  141. rectangleTex, GrColorType::kRGBA_8888, origin,
  142. kBorrow_GrWrapOwnership, GrWrapCacheable::kNo, kRW_GrIOType);
  143. if (!rectProxy) {
  144. ERRORF(reporter, "Error creating proxy for rectangle texture.");
  145. GR_GL_CALL(glContext->gl(), DeleteTextures(1, &rectTexID));
  146. continue;
  147. }
  148. SkASSERT(rectProxy->mipMapped() == GrMipMapped::kNo);
  149. SkASSERT(rectProxy->peekTexture()->texturePriv().mipMapped() == GrMipMapped::kNo);
  150. SkASSERT(rectProxy->textureType() == GrTextureType::kRectangle);
  151. SkASSERT(rectProxy->peekTexture()->texturePriv().textureType() ==
  152. GrTextureType::kRectangle);
  153. SkASSERT(rectProxy->hasRestrictedSampling());
  154. SkASSERT(rectProxy->peekTexture()->texturePriv().hasRestrictedSampling());
  155. test_basic_draw_as_src(reporter, context, rectProxy, GrColorType::kRGBA_8888, refPixels);
  156. // Test copy to both a texture and RT
  157. test_copy_from_surface(reporter, context, rectProxy.get(), GrColorType::kRGBA_8888,
  158. refPixels, "RectangleTexture-copy-from");
  159. sk_sp<GrSurfaceContext> rectContext = context->priv().makeWrappedSurfaceContext(
  160. std::move(rectProxy), GrColorType::kRGBA_8888, kPremul_SkAlphaType);
  161. SkASSERT(rectContext);
  162. test_read_pixels(reporter, rectContext.get(), refPixels, "RectangleTexture-read");
  163. test_copy_to_surface(reporter, context, rectContext.get(), "RectangleTexture-copy-to");
  164. test_write_pixels(reporter, rectContext.get(), true, "RectangleTexture-write");
  165. test_clear(reporter, rectContext.get());
  166. GR_GL_CALL(glContext->gl(), DeleteTextures(1, &rectTexID));
  167. }
  168. }