// This tests that GrTextureStripAtlas flushes pending IO on the texture it acquires. DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrTextureStripAtlasFlush, reporter, ctxInfo) { GrContext* context = ctxInfo.grContext(); GrSurfaceDesc desc; desc.fWidth = 32; desc.fHeight = 32; desc.fConfig = kRGBA_8888_GrPixelConfig; GrTexture* texture = context->textureProvider()->createTexture(desc, SkBudgeted::kYes, nullptr, 0); GrSurfaceDesc targetDesc = desc; targetDesc.fFlags = kRenderTarget_GrSurfaceFlag; GrTexture* target = context->textureProvider()->createTexture(targetDesc, SkBudgeted::kYes, nullptr, 0); SkAutoTMalloc<uint32_t> pixels(desc.fWidth * desc.fHeight); memset(pixels.get(), 0xFF, sizeof(uint32_t) * desc.fWidth * desc.fHeight); texture->writePixels(0, 0, desc.fWidth, desc.fHeight, kRGBA_8888_GrPixelConfig, pixels.get()); // Add a pending read to the texture, and then make it available for reuse. context->copySurface(target, texture); texture->unref(); // Create an atlas with parameters that allow it to reuse the texture. GrTextureStripAtlas::Desc atlasDesc; atlasDesc.fContext = context; atlasDesc.fConfig = desc.fConfig; atlasDesc.fWidth = desc.fWidth; atlasDesc.fHeight = desc.fHeight; atlasDesc.fRowHeight = 1; GrTextureStripAtlas* atlas = GrTextureStripAtlas::GetAtlas(atlasDesc); // Write to the atlas' texture. SkImageInfo info = SkImageInfo::MakeN32(desc.fWidth, desc.fHeight, kPremul_SkAlphaType); size_t rowBytes = desc.fWidth * GrBytesPerPixel(desc.fConfig); SkBitmap bitmap; bitmap.allocPixels(info, rowBytes); memset(bitmap.getPixels(), 1, rowBytes * desc.fHeight); int row = atlas->lockRow(bitmap); if (!context->caps()->preferVRAMUseOverFlushes()) REPORTER_ASSERT(reporter, texture == atlas->getTexture()); // The atlas' use of its texture shouldn't change which pixels got copied to the target. SkAutoTMalloc<uint32_t> actualPixels(desc.fWidth * desc.fHeight); bool success = target->readPixels(0, 0, desc.fWidth, desc.fHeight, kRGBA_8888_GrPixelConfig, actualPixels.get()); REPORTER_ASSERT(reporter, success); REPORTER_ASSERT(reporter, !memcmp(pixels.get(), actualPixels.get(), sizeof(uint32_t) * desc.fWidth * desc.fHeight)); target->unref(); atlas->unlockRow(row); }
DEF_GPUTEST(ReadWriteAlpha, reporter, factory) { for (int type = 0; type < GrContextFactory::kLastGLContextType; ++type) { GrContextFactory::GLContextType glType = static_cast<GrContextFactory::GLContextType>(type); if (!GrContextFactory::IsRenderingGLContext(glType)) { continue; } GrContext* context = factory->get(glType); if (NULL == context) { continue; } unsigned char textureData[X_SIZE][Y_SIZE]; memset(textureData, 0, X_SIZE * Y_SIZE); GrSurfaceDesc desc; // let Skia know we will be using this texture as a render target desc.fFlags = kRenderTarget_GrSurfaceFlag; // it is a single channel texture desc.fConfig = kAlpha_8_GrPixelConfig; desc.fWidth = X_SIZE; desc.fHeight = Y_SIZE; // We are initializing the texture with zeros here GrTexture* texture = context->createTexture(desc, false, textureData, 0); if (!texture) { return; } SkAutoTUnref<GrTexture> au(texture); // create a distinctive texture for (int y = 0; y < Y_SIZE; ++y) { for (int x = 0; x < X_SIZE; ++x) { textureData[x][y] = x*Y_SIZE+y; } } // upload the texture texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig, textureData, 0); unsigned char readback[X_SIZE][Y_SIZE]; // clear readback to something non-zero so we can detect readback failures memset(readback, 0x1, X_SIZE * Y_SIZE); // read the texture back texture->readPixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig, readback, 0); // make sure the original & read back versions match bool match = true; for (int y = 0; y < Y_SIZE; ++y) { for (int x = 0; x < X_SIZE; ++x) { if (textureData[x][y] != readback[x][y]) { match = false; } } } REPORTER_ASSERT(reporter, match); // Now try writing on the single channel texture SkSurfaceProps props(SkSurfaceProps::kLegacyFontHost_InitType); SkAutoTUnref<SkBaseDevice> device(SkGpuDevice::Create(texture->asRenderTarget(), &props)); SkCanvas canvas(device); SkPaint paint; const SkRect rect = SkRect::MakeLTRB(-10, -10, X_SIZE + 10, Y_SIZE + 10); paint.setColor(SK_ColorWHITE); canvas.drawRect(rect, paint); texture->readPixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig, readback, 0); match = true; for (int y = 0; y < Y_SIZE; ++y) { for (int x = 0; x < X_SIZE; ++x) { if (0xFF != readback[x][y]) { match = false; } } } REPORTER_ASSERT(reporter, match); } }