void GrGLProgram::setRenderTargetState(const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline) { // Load the RT height uniform if it is needed to y-flip gl_FragCoord. if (fBuiltinUniformHandles.fRTHeightUni.isValid() && fRenderTargetState.fRenderTargetSize.fHeight != pipeline.getRenderTarget()->height()) { fProgramDataManager.set1f(fBuiltinUniformHandles.fRTHeightUni, SkIntToScalar(pipeline.getRenderTarget()->height())); } // set RT adjustment const GrRenderTarget* rt = pipeline.getRenderTarget(); SkISize size; size.set(rt->width(), rt->height()); if (!primProc.isPathRendering()) { if (fRenderTargetState.fRenderTargetOrigin != rt->origin() || fRenderTargetState.fRenderTargetSize != size) { fRenderTargetState.fRenderTargetSize = size; fRenderTargetState.fRenderTargetOrigin = rt->origin(); float rtAdjustmentVec[4]; fRenderTargetState.getRTAdjustmentVec(rtAdjustmentVec); fProgramDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec); } } else { SkASSERT(fGpu->glCaps().shaderCaps()->pathRenderingSupport()); const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>(); fGpu->glPathRendering()->setProjectionMatrix(pathProc.viewMatrix(), size, rt->origin()); } }
void drawHere(SkCanvas* canvas, SkFilterQuality filter, SkScalar dx, SkScalar dy) { SkCanvas* origCanvas = canvas; SkAutoCanvasRestore acr(canvas, true); SkISize size = SkISize::Make(fImage->width(), fImage->height()); SkAutoTUnref<SkSurface> surface; if (fShowFatBits) { // scale up so we don't clip rotations SkImageInfo info = SkImageInfo::MakeN32(fImage->width() * 2, fImage->height() * 2, kOpaque_SkAlphaType); surface.reset(make_surface(canvas, info)); canvas = surface->getCanvas(); canvas->drawColor(SK_ColorWHITE); size.set(info.width(), info.height()); } else { canvas->translate(SkScalarHalf(fCell.width() - fImage->width()), SkScalarHalf(fCell.height() - fImage->height())); } this->drawTheImage(canvas, size, filter, dx, dy); if (surface) { SkAutoTUnref<SkImage> orig(surface->newImageSnapshot()); SkAutoTUnref<SkImage> zoomed(zoom_up(orig)); origCanvas->drawImage(zoomed, SkScalarHalf(fCell.width() - zoomed->width()), SkScalarHalf(fCell.height() - zoomed->height())); } }
static void TestSize(skiatest::Reporter* reporter) { TestISize(reporter); SkSize a, b; int ix = 5; int iy = 3; SkScalar x = SkIntToScalar(ix); SkScalar y = SkIntToScalar(iy); a.set(0, 0); REPORTER_ASSERT(reporter, a.isEmpty()); a.set(x, -x); REPORTER_ASSERT(reporter, a.isEmpty()); a.clampNegToZero(); REPORTER_ASSERT(reporter, a.isEmpty()); b.set(x, 0); REPORTER_ASSERT(reporter, a == b); a.set(y, x); REPORTER_ASSERT(reporter, !a.isEmpty()); b = a; REPORTER_ASSERT(reporter, !b.isEmpty()); REPORTER_ASSERT(reporter, a == b); REPORTER_ASSERT(reporter, !(a != b)); REPORTER_ASSERT(reporter, a.fWidth == b.fWidth && a.fHeight == b.fHeight); SkISize ia; ia.set(ix, iy); a.set(x, y); REPORTER_ASSERT(reporter, a.toRound() == ia); };
void GrGLProgram::setMatrixAndRenderTargetHeight(const GrDrawState& drawState) { const GrRenderTarget* rt = drawState.getRenderTarget(); SkISize size; size.set(rt->width(), rt->height()); // Load the RT height uniform if it is needed to y-flip gl_FragCoord. if (fBuilderOutput.fUniformHandles.fRTHeightUni.isValid() && fMatrixState.fRenderTargetSize.fHeight != size.fHeight) { fUniformManager->set1f(fBuilderOutput.fUniformHandles.fRTHeightUni, SkIntToScalar(size.fHeight)); } if (!fBuilderOutput.fHasVertexShader) { SkASSERT(!fBuilderOutput.fUniformHandles.fViewMatrixUni.isValid()); SkASSERT(!fBuilderOutput.fUniformHandles.fRTAdjustmentUni.isValid()); fGpu->setProjectionMatrix(drawState.getViewMatrix(), size, rt->origin()); } else if (fMatrixState.fRenderTargetOrigin != rt->origin() || fMatrixState.fRenderTargetSize != size || !fMatrixState.fViewMatrix.cheapEqualTo(drawState.getViewMatrix())) { SkASSERT(fBuilderOutput.fUniformHandles.fViewMatrixUni.isValid()); fMatrixState.fViewMatrix = drawState.getViewMatrix(); fMatrixState.fRenderTargetSize = size; fMatrixState.fRenderTargetOrigin = rt->origin(); GrGLfloat viewMatrix[3 * 3]; fMatrixState.getGLMatrix<3>(viewMatrix); fUniformManager->setMatrix3f(fBuilderOutput.fUniformHandles.fViewMatrixUni, viewMatrix); GrGLfloat rtAdjustmentVec[4]; fMatrixState.getRTAdjustmentVec(rtAdjustmentVec); fUniformManager->set4fv(fBuilderOutput.fUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec); } }
void GrGLNvprProgramBase::onSetMatrixAndRenderTargetHeight(GrGpu::DrawType drawType, const GrOptDrawState& optState) { SkASSERT(GrGpu::IsPathRenderingDrawType(drawType)); const GrRenderTarget* rt = optState.getRenderTarget(); SkISize size; size.set(rt->width(), rt->height()); fGpu->glPathRendering()->setProjectionMatrix(optState.getViewMatrix(), size, rt->origin()); }
static void test_treatAsSprite(skiatest::Reporter* reporter) { const unsigned bilerBits = kSkSubPixelBitsForBilerp; SkMatrix mat; SkISize size; SkRandom rand; // assert: translate-only no-filter can always be treated as sprite for (int i = 0; i < 1000; ++i) { rand_matrix(&mat, rand, SkMatrix::kTranslate_Mask); for (int j = 0; j < 1000; ++j) { rand_size(&size, rand); REPORTER_ASSERT(reporter, treat_as_sprite(mat, size, 0)); } } // assert: rotate/perspect is never treated as sprite for (int i = 0; i < 1000; ++i) { rand_matrix(&mat, rand, SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Mask); for (int j = 0; j < 1000; ++j) { rand_size(&size, rand); REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, 0)); REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, bilerBits)); } } size.set(500, 600); const SkScalar tooMuchSubpixel = 100.1f; mat.setTranslate(tooMuchSubpixel, 0); REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, bilerBits)); mat.setTranslate(0, tooMuchSubpixel); REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, bilerBits)); const SkScalar tinySubPixel = 100.02f; mat.setTranslate(tinySubPixel, 0); REPORTER_ASSERT(reporter, treat_as_sprite(mat, size, bilerBits)); mat.setTranslate(0, tinySubPixel); REPORTER_ASSERT(reporter, treat_as_sprite(mat, size, bilerBits)); const SkScalar twoThirds = SK_Scalar1 * 2 / 3; const SkScalar bigScale = (size.width() + twoThirds) / size.width(); mat.setScale(bigScale, bigScale); REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, false)); REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, bilerBits)); const SkScalar oneThird = SK_Scalar1 / 3; const SkScalar smallScale = (size.width() + oneThird) / size.width(); mat.setScale(smallScale, smallScale); REPORTER_ASSERT(reporter, treat_as_sprite(mat, size, false)); REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, bilerBits)); const SkScalar oneFortyth = SK_Scalar1 / 40; const SkScalar tinyScale = (size.width() + oneFortyth) / size.width(); mat.setScale(tinyScale, tinyScale); REPORTER_ASSERT(reporter, treat_as_sprite(mat, size, false)); REPORTER_ASSERT(reporter, treat_as_sprite(mat, size, bilerBits)); }
void GrGLPathProgram::onSetRenderTargetState(const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline) { SkASSERT(!primProc.willUseGeoShader() && primProc.numAttribs() == 0); const GrRenderTarget* rt = pipeline.getRenderTarget(); SkISize size; size.set(rt->width(), rt->height()); const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>(); fGpu->glPathRendering()->setProjectionMatrix(pathProc.viewMatrix(), size, rt->origin()); }
void GrGLProgram::onSetRenderTargetState(const GrPrimitiveProcessor&, const GrPipeline& pipeline) { const GrRenderTarget* rt = pipeline.getRenderTarget(); SkISize size; size.set(rt->width(), rt->height()); if (fRenderTargetState.fRenderTargetOrigin != rt->origin() || fRenderTargetState.fRenderTargetSize != size) { fRenderTargetState.fRenderTargetSize = size; fRenderTargetState.fRenderTargetOrigin = rt->origin(); GrGLfloat rtAdjustmentVec[4]; fRenderTargetState.getRTAdjustmentVec(rtAdjustmentVec); fProgramDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec); } }
void GrVkPipelineState::setRenderTargetState(const GrRenderTarget* rt, GrSurfaceOrigin origin) { // Load the RT height uniform if it is needed to y-flip gl_FragCoord. if (fBuiltinUniformHandles.fRTHeightUni.isValid() && fRenderTargetState.fRenderTargetSize.fHeight != rt->height()) { fDataManager.set1f(fBuiltinUniformHandles.fRTHeightUni, SkIntToScalar(rt->height())); } // set RT adjustment SkISize size; size.set(rt->width(), rt->height()); SkASSERT(fBuiltinUniformHandles.fRTAdjustmentUni.isValid()); if (fRenderTargetState.fRenderTargetOrigin != origin || fRenderTargetState.fRenderTargetSize != size) { fRenderTargetState.fRenderTargetSize = size; fRenderTargetState.fRenderTargetOrigin = origin; float rtAdjustmentVec[4]; fRenderTargetState.getRTAdjustmentVec(rtAdjustmentVec); fDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec); } }
void GrGLProgram::onSetMatrixAndRenderTargetHeight(GrGpu::DrawType drawType, const GrOptDrawState& optState) { const GrRenderTarget* rt = optState.getRenderTarget(); SkISize size; size.set(rt->width(), rt->height()); if (fMatrixState.fRenderTargetOrigin != rt->origin() || fMatrixState.fRenderTargetSize != size || !fMatrixState.fViewMatrix.cheapEqualTo(optState.getViewMatrix())) { SkASSERT(fBuiltinUniformHandles.fViewMatrixUni.isValid()); fMatrixState.fViewMatrix = optState.getViewMatrix(); fMatrixState.fRenderTargetSize = size; fMatrixState.fRenderTargetOrigin = rt->origin(); GrGLfloat viewMatrix[3 * 3]; fMatrixState.getGLMatrix<3>(viewMatrix); fProgramDataManager.setMatrix3f(fBuiltinUniformHandles.fViewMatrixUni, viewMatrix); GrGLfloat rtAdjustmentVec[4]; fMatrixState.getRTAdjustmentVec(rtAdjustmentVec); fProgramDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec); } }
void GrGpuGL::flushViewMatrix(DrawType type) { const GrGLRenderTarget* rt = static_cast<const GrGLRenderTarget*>(this->getDrawState().getRenderTarget()); SkISize viewportSize; const GrGLIRect& viewport = rt->getViewport(); viewportSize.set(viewport.fWidth, viewport.fHeight); const SkMatrix& vm = this->getDrawState().getViewMatrix(); if (kStencilPath_DrawType == type) { if (fHWPathMatrixState.fViewMatrix != vm || fHWPathMatrixState.fRTSize != viewportSize) { // rescale the coords from skia's "device" coords to GL's normalized coords, // and perform a y-flip. SkMatrix m; m.setScale(SkIntToScalar(2) / rt->width(), SkIntToScalar(-2) / rt->height()); m.postTranslate(-SK_Scalar1, SK_Scalar1); m.preConcat(vm); // GL wants a column-major 4x4. GrGLfloat mv[] = { // col 0 SkScalarToFloat(m[SkMatrix::kMScaleX]), SkScalarToFloat(m[SkMatrix::kMSkewY]), 0, SkScalarToFloat(m[SkMatrix::kMPersp0]), // col 1 SkScalarToFloat(m[SkMatrix::kMSkewX]), SkScalarToFloat(m[SkMatrix::kMScaleY]), 0, SkScalarToFloat(m[SkMatrix::kMPersp1]), // col 2 0, 0, 0, 0, // col3 SkScalarToFloat(m[SkMatrix::kMTransX]), SkScalarToFloat(m[SkMatrix::kMTransY]), 0.0f, SkScalarToFloat(m[SkMatrix::kMPersp2]) }; GL_CALL(MatrixMode(GR_GL_PROJECTION)); GL_CALL(LoadMatrixf(mv)); fHWPathMatrixState.fViewMatrix = vm; fHWPathMatrixState.fRTSize = viewportSize; } } else if (!fCurrentProgram->fViewMatrix.cheapEqualTo(vm) || fCurrentProgram->fViewportSize != viewportSize) { SkMatrix m; m.setAll( SkIntToScalar(2) / viewportSize.fWidth, 0, -SK_Scalar1, 0,-SkIntToScalar(2) / viewportSize.fHeight, SK_Scalar1, 0, 0, SkMatrix::I()[8]); m.setConcat(m, vm); // ES doesn't allow you to pass true to the transpose param, // so do our own transpose GrGLfloat mt[] = { SkScalarToFloat(m[SkMatrix::kMScaleX]), SkScalarToFloat(m[SkMatrix::kMSkewY]), SkScalarToFloat(m[SkMatrix::kMPersp0]), SkScalarToFloat(m[SkMatrix::kMSkewX]), SkScalarToFloat(m[SkMatrix::kMScaleY]), SkScalarToFloat(m[SkMatrix::kMPersp1]), SkScalarToFloat(m[SkMatrix::kMTransX]), SkScalarToFloat(m[SkMatrix::kMTransY]), SkScalarToFloat(m[SkMatrix::kMPersp2]) }; fCurrentProgram->fUniformManager.setMatrix3f( fCurrentProgram->fUniformHandles.fViewMatrixUni, mt); fCurrentProgram->fViewMatrix = vm; fCurrentProgram->fViewportSize = viewportSize; } }
static void test_treatAsSprite(skiatest::Reporter* reporter) { SkMatrix mat; SkISize size; SkRandom rand; SkPaint noaaPaint; SkPaint aaPaint; aaPaint.setAntiAlias(true); // assert: translate-only no-aa can always be treated as sprite for (int i = 0; i < 1000; ++i) { rand_matrix(&mat, rand, SkMatrix::kTranslate_Mask); for (int j = 0; j < 1000; ++j) { rand_size(&size, rand); REPORTER_ASSERT(reporter, SkTreatAsSprite(mat, size, noaaPaint)); } } // assert: rotate/perspect is never treated as sprite for (int i = 0; i < 1000; ++i) { rand_matrix(&mat, rand, SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Mask); for (int j = 0; j < 1000; ++j) { rand_size(&size, rand); REPORTER_ASSERT(reporter, !SkTreatAsSprite(mat, size, noaaPaint)); REPORTER_ASSERT(reporter, !SkTreatAsSprite(mat, size, aaPaint)); } } size.set(500, 600); const SkScalar tooMuchSubpixel = 100.1f; mat.setTranslate(tooMuchSubpixel, 0); REPORTER_ASSERT(reporter, !SkTreatAsSprite(mat, size, aaPaint)); mat.setTranslate(0, tooMuchSubpixel); REPORTER_ASSERT(reporter, !SkTreatAsSprite(mat, size, aaPaint)); const SkScalar tinySubPixel = 100.02f; mat.setTranslate(tinySubPixel, 0); REPORTER_ASSERT(reporter, SkTreatAsSprite(mat, size, aaPaint)); mat.setTranslate(0, tinySubPixel); REPORTER_ASSERT(reporter, SkTreatAsSprite(mat, size, aaPaint)); const SkScalar twoThirds = SK_Scalar1 * 2 / 3; const SkScalar bigScale = (size.width() + twoThirds) / size.width(); mat.setScale(bigScale, bigScale); REPORTER_ASSERT(reporter, !SkTreatAsSprite(mat, size, noaaPaint)); REPORTER_ASSERT(reporter, !SkTreatAsSprite(mat, size, aaPaint)); const SkScalar oneThird = SK_Scalar1 / 3; const SkScalar smallScale = (size.width() + oneThird) / size.width(); mat.setScale(smallScale, smallScale); REPORTER_ASSERT(reporter, SkTreatAsSprite(mat, size, noaaPaint)); REPORTER_ASSERT(reporter, !SkTreatAsSprite(mat, size, aaPaint)); const SkScalar oneFortyth = SK_Scalar1 / 40; const SkScalar tinyScale = (size.width() + oneFortyth) / size.width(); mat.setScale(tinyScale, tinyScale); REPORTER_ASSERT(reporter, SkTreatAsSprite(mat, size, noaaPaint)); REPORTER_ASSERT(reporter, SkTreatAsSprite(mat, size, aaPaint)); }