// Ensure that the 'getConservativeBounds' calls are returning bounds clamped // to the render target static void test_clip_bounds(skiatest::Reporter* reporter, GrContext* context) { static const int kXSize = 100; static const int kYSize = 100; GrTextureDesc desc; desc.fFlags = kRenderTarget_GrTextureFlagBit; desc.fConfig = kAlpha_8_GrPixelConfig; desc.fWidth = kXSize; desc.fHeight = kYSize; GrTexture* texture = context->createUncachedTexture(desc, NULL, 0); if (!texture) { return; } SkAutoUnref au(texture); SkIRect intScreen = SkIRect::MakeWH(kXSize, kYSize); SkRect screen; screen = SkRect::MakeWH(SkIntToScalar(kXSize), SkIntToScalar(kYSize)); SkRect clipRect(screen); clipRect.outset(10, 10); // create a clip stack that will (trivially) reduce to a single rect that // is larger than the screen SkClipStack stack; stack.clipDevRect(clipRect, SkRegion::kReplace_Op, false); bool isIntersectionOfRects = true; SkRect devStackBounds; stack.getConservativeBounds(0, 0, kXSize, kYSize, &devStackBounds, &isIntersectionOfRects); // make sure that the SkClipStack is behaving itself REPORTER_ASSERT(reporter, screen == devStackBounds); REPORTER_ASSERT(reporter, isIntersectionOfRects); // wrap the SkClipStack in a GrClipData GrClipData clipData; clipData.fClipStack = &stack; SkIRect devGrClipDataBound; clipData.getConservativeBounds(texture, &devGrClipDataBound, &isIntersectionOfRects); // make sure that GrClipData is behaving itself REPORTER_ASSERT(reporter, intScreen == devGrClipDataBound); REPORTER_ASSERT(reporter, isIntersectionOfRects); }
//////////////////////////////////////////////////////////////////////////////// // Shared preamble between gpu and SW-only AA clip mask creation paths. // Handles caching, determination of clip mask bound & allocation (if needed) // of the result texture // Returns true if there is no more work to be done (i.e., we got a cache hit) bool GrClipMaskManager::clipMaskPreamble(const GrClipData& clipDataIn, GrTexture** result, GrIRect* devResultBounds) { GrDrawState* origDrawState = fGpu->drawState(); GrAssert(origDrawState->isClipState()); GrRenderTarget* rt = origDrawState->getRenderTarget(); GrAssert(NULL != rt); // unlike the stencil path the alpha path is not bound to the size of the // render target - determine the minimum size required for the mask // Note: intBounds is in device (as opposed to canvas) coordinates clipDataIn.getConservativeBounds(rt, devResultBounds); // need to outset a pixel since the standard bounding box computation // path doesn't leave any room for antialiasing (esp. w.r.t. rects) devResultBounds->outset(1, 1); // TODO: make sure we don't outset if bounds are still 0,0 @ min if (fAACache.canReuse(*clipDataIn.fClipStack, *devResultBounds)) { *result = fAACache.getLastMask(); fAACache.getLastBound(devResultBounds); return true; } this->setupCache(*clipDataIn.fClipStack, *devResultBounds); return false; }