static SkGrPixelRef* copy_to_new_texture_pixelref(GrTexture* texture, SkColorType dstCT, SkColorProfileType dstPT, const SkIRect* subset) { if (NULL == texture || kUnknown_SkColorType == dstCT) { return NULL; } GrContext* context = texture->getContext(); if (NULL == context) { return NULL; } GrSurfaceDesc desc; SkIRect srcRect; if (!subset) { desc.fWidth = texture->width(); desc.fHeight = texture->height(); srcRect = SkIRect::MakeWH(texture->width(), texture->height()); } else { SkASSERT(SkIRect::MakeWH(texture->width(), texture->height()).contains(*subset)); // Create a new texture that is the size of subset. desc.fWidth = subset->width(); desc.fHeight = subset->height(); srcRect = *subset; } desc.fFlags = kRenderTarget_GrSurfaceFlag; desc.fConfig = SkImageInfo2GrPixelConfig(dstCT, kPremul_SkAlphaType, dstPT); GrTexture* dst = context->createTexture(desc, false, NULL, 0); if (NULL == dst) { return NULL; } // Blink is relying on the above copy being sent to GL immediately in the case when the source // is a WebGL canvas backing store. We could have a TODO to remove this flush flag, but we have // a larger TODO to remove SkGrPixelRef entirely. context->copySurface(dst->asRenderTarget(), texture, srcRect, SkIPoint::Make(0,0), GrContext::kFlushWrites_PixelOp); SkImageInfo info = SkImageInfo::Make(desc.fWidth, desc.fHeight, dstCT, kPremul_SkAlphaType, dstPT); SkGrPixelRef* pixelRef = SkNEW_ARGS(SkGrPixelRef, (info, dst)); SkSafeUnref(dst); return pixelRef; }
// temporary disable; see below for explanation static bool gpu_blur_path(GrContextFactory* factory, const SkPath& path, SkScalar gaussianSigma, int* result, int resultCount) { GrContext* grContext = factory->get(GrContextFactory::kNative_GLContextType); if (NULL == grContext) { return false; } GrSurfaceDesc desc; desc.fConfig = kSkia8888_GrPixelConfig; desc.fFlags = kRenderTarget_GrSurfaceFlag; desc.fWidth = resultCount; desc.fHeight = 30; desc.fSampleCnt = 0; SkAutoTUnref<GrTexture> texture(grContext->createTexture(desc, false, NULL, 0)); SkAutoTUnref<SkGpuDevice> device(new SkGpuDevice (grContext, texture.get())); SkCanvas canvas(device.get()); blur_path(&canvas, path, gaussianSigma); readback(&canvas, result, resultCount); return true; }
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); } }