/**
 * Calculates whether content drawn within the passed bounds would be outside of, or intersect with
 * the clipRect. Does not modify the scissor.
 *
 * @param clipRequired if not null, will be set to true if element intersects clip
 *         (and wasn't rejected)
 *
 * @param snapOut if set, the geometry will be treated as having an AA ramp.
 *         See Rect::snapGeometryToPixelBoundaries()
 */
bool CanvasState::calculateQuickRejectForScissor(float left, float top, float right, float bottom,
                                                 bool* clipRequired, bool* roundRectClipRequired,
                                                 bool snapOut) const {
    if (bottom <= top || right <= left) {
        return true;
    }

    Rect r(left, top, right, bottom);
    currentTransform()->mapRect(r);
    r.snapGeometryToPixelBoundaries(snapOut);

    Rect clipRect(currentRenderTargetClip());
    clipRect.snapToPixelBoundaries();

    if (!clipRect.intersects(r)) return true;

    // clip is required if geometry intersects clip rect
    if (clipRequired) {
        *clipRequired = !clipRect.contains(r);
    }

    // round rect clip is required if RR clip exists, and geometry intersects its corners
    if (roundRectClipRequired) {
        *roundRectClipRequired = mSnapshot->roundRectClipState != nullptr &&
                                 mSnapshot->roundRectClipState->areaRequiresRoundRectClip(r);
    }
    return false;
}
Пример #2
0
 void beginClipping(int x, int y, int width, int height, int screenHeight)
 {
     // Apply current transformation.
     
     double left = x, right = x + width;
     double top = y, bottom = y + height;
     
     applyTransform(currentTransform(), left, top);
     applyTransform(currentTransform(), right, bottom);
     
     int physX = std::min(left, right);
     int physY = std::min(top, bottom);
     int physWidth = std::abs(int(left - right));
     int physHeight = std::abs(int(top - bottom));
     
     // Adjust for OpenGL having the wrong idea of where y=0 is.
     // TODO: This should really happen *right before* setting up
     // the glScissor.
     physY = screenHeight - physY - physHeight;
     
     clipRectStack.beginClipping(physX, physY, physWidth, physHeight);
 }
void CanvasState::setClippingOutline(LinearAllocator& allocator, const Outline* outline) {
    Rect bounds;
    float radius;
    if (!outline->getAsRoundRect(&bounds, &radius)) return;  // only RR supported

    bool outlineIsRounded = MathUtils::isPositive(radius);
    if (!outlineIsRounded || currentTransform()->isSimple()) {
        // TODO: consider storing this rect separately, so that this can't be replaced with clip ops
        clipRect(bounds.left, bounds.top, bounds.right, bounds.bottom, SkClipOp::kIntersect);
    }
    if (outlineIsRounded) {
        setClippingRoundRect(allocator, bounds, radius, false);
    }
}
Пример #4
0
 void scheduleDrawOp(DrawOp op)
 {
     if (clipRectStack.clippedWorldAway())
         return;
     
     #ifdef GOSU_IS_IPHONE
     // No triangles, no lines supported
     assert (op.verticesOrBlockIndex == 4);
     #endif
     
     op.renderState.transform = &currentTransform();
     if (const ClipRect* cr = clipRectStack.maybeEffectiveRect())
         op.renderState.clipRect = *cr;
     ops.push_back(op);
 }
bool CanvasState::quickRejectConservative(float left, float top, float right, float bottom) const {
    if (bottom <= top || right <= left) {
        return true;
    }

    Rect r(left, top, right, bottom);
    currentTransform()->mapRect(r);
    r.roundOut();  // rounded out to be conservative

    Rect clipRect(currentRenderTargetClip());
    clipRect.snapToPixelBoundaries();

    if (!clipRect.intersects(r)) return true;

    return false;
}
Пример #6
0
 void scheduleGL(std::tr1::function<void()> glBlock, ZPos z)
 {
     // TODO: Document this case: Clipped-away GL blocks are *not* being run.
     if (clipRectStack.clippedWorldAway())
         return;
     
     int complementOfBlockIndex = ~(int)glBlocks.size();
     glBlocks.push_back(glBlock);
     
     DrawOp op;
     op.verticesOrBlockIndex = complementOfBlockIndex;
     op.renderState.transform = &currentTransform();
     if (const ClipRect* cr = clipRectStack.maybeEffectiveRect())
         op.renderState.clipRect = *cr;
     op.z = z;
     ops.push_back(op);
 }
Пример #7
0
void OpenGLInstance::commit(const OpenGLViewport &viewport)
{
  P(OpenGLInstancePrivate);
  OpenGLBuffer::RangeAccessFlags flags =
    OpenGLBuffer::RangeUnsynchronized   |
    OpenGLBuffer::RangeInvalidateBuffer |
    OpenGLBuffer::RangeWrite;

  p.m_buffer.bind();

  // Send data to the GPU
  {
    OpenGLInstanceData *data = (OpenGLInstanceData*)p.m_buffer.mapRange(0, sizeof(OpenGLInstanceData), flags);
    data->m_currModelView = viewport.current().worldToView()  * Karma::ToGlm(currentTransform().toMatrix() );
    data->m_prevModelView = viewport.previous().worldToView() * Karma::ToGlm(previousTransform().toMatrix());
    data->m_normalTransform = glm::transpose(glm::inverse(data->m_currModelView));
    p.m_buffer.unmap();
  }

  update(); // Updates current/previous pairs
  p.m_buffer.release();
}
Пример #8
0
 void pushTransform(const Transform& transform)
 {
     individualTransforms.push_back(transform);
     Transform result = multiply(transform, currentTransform());
     makeCurrentTransform(result);
 }