// 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);
}
Esempio n. 2
0
////////////////////////////////////////////////////////////////////////////////
// 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;
}