Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8d13ef3c authored by Romain Guy's avatar Romain Guy Committed by Android (Google) Code Review
Browse files

Merge "Separate interface definition and implementation of Snapshot"

parents b545eaa9 ada4d53d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ ifeq ($(USE_OPENGL_RENDERER),true)
		ShapeCache.cpp \
		SkiaColorFilter.cpp \
		SkiaShader.cpp \
		Snapshot.cpp \
		TextureCache.cpp \
		TextDropShadowCache.cpp
	
+2 −2
Original line number Diff line number Diff line
@@ -38,8 +38,8 @@
#define LAYER_SIZE 64

// Defines the size in bits of the stencil buffer
// Note: We only want 1 bit, but in practice we'll get 8 bits on all GPUs
//       for the foreseeable future
// Note: Only 1 bit is required for clipping but more bits are required
// to properly implement the winding fill rule when rasterizing paths
#define STENCIL_BUFFER_SIZE 0

/**

libs/hwui/Snapshot.cpp

0 → 100644
+154 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "Snapshot.h"

#include <SkCanvas.h>

namespace android {
namespace uirenderer {

///////////////////////////////////////////////////////////////////////////////
// Constructors
///////////////////////////////////////////////////////////////////////////////

Snapshot::Snapshot(): flags(0), previous(NULL), layer(NULL), fbo(0),
        invisible(false), empty(false) {

    transform = &mTransformRoot;
    clipRect = &mClipRectRoot;
    region = NULL;
}

/**
 * Copies the specified snapshot/ The specified snapshot is stored as
 * the previous snapshot.
 */
Snapshot::Snapshot(const sp<Snapshot>& s, int saveFlags):
        flags(0), previous(s), layer(NULL), fbo(s->fbo),
        invisible(s->invisible), empty(false),
        viewport(s->viewport), height(s->height) {

    if (saveFlags & SkCanvas::kMatrix_SaveFlag) {
        mTransformRoot.load(*s->transform);
        transform = &mTransformRoot;
    } else {
        transform = s->transform;
    }

    if (saveFlags & SkCanvas::kClip_SaveFlag) {
        mClipRectRoot.set(*s->clipRect);
        clipRect = &mClipRectRoot;
    } else {
        clipRect = s->clipRect;
    }

    if (s->flags & Snapshot::kFlagFboTarget) {
        flags |= Snapshot::kFlagFboTarget;
        region = s->region;
    } else {
        region = NULL;
    }
}

///////////////////////////////////////////////////////////////////////////////
// Clipping
///////////////////////////////////////////////////////////////////////////////

bool Snapshot::clip(float left, float top, float right, float bottom, SkRegion::Op op) {
    Rect r(left, top, right, bottom);
    transform->mapRect(r);
    return clipTransformed(r, op);
}

bool Snapshot::clipTransformed(const Rect& r, SkRegion::Op op) {
    bool clipped = false;

    // NOTE: The unimplemented operations require support for regions
    // Supporting regions would require using a stencil buffer instead
    // of the scissor. The stencil buffer itself is not too expensive
    // (memory cost excluded) but on fillrate limited devices, managing
    // the stencil might have a negative impact on the framerate.
    switch (op) {
        case SkRegion::kDifference_Op:
            break;
        case SkRegion::kIntersect_Op:
            clipped = clipRect->intersect(r);
            if (!clipped) {
                clipRect->setEmpty();
                clipped = true;
            }
            break;
        case SkRegion::kUnion_Op:
            clipped = clipRect->unionWith(r);
            break;
        case SkRegion::kXOR_Op:
            break;
        case SkRegion::kReverseDifference_Op:
            break;
        case SkRegion::kReplace_Op:
            clipRect->set(r);
            clipped = true;
            break;
    }

    if (clipped) {
        flags |= Snapshot::kFlagClipSet;
    }

    return clipped;
}

void Snapshot::setClip(float left, float top, float right, float bottom) {
    clipRect->set(left, top, right, bottom);
    flags |= Snapshot::kFlagClipSet;
}

const Rect& Snapshot::getLocalClip() {
    mat4 inverse;
    inverse.loadInverse(*transform);

    mLocalClip.set(*clipRect);
    inverse.mapRect(mLocalClip);

    return mLocalClip;
}

void Snapshot::resetClip(float left, float top, float right, float bottom) {
    clipRect = &mClipRectRoot;
    clipRect->set(left, top, right, bottom);
    flags |= Snapshot::kFlagClipSet;
}

///////////////////////////////////////////////////////////////////////////////
// Transforms
///////////////////////////////////////////////////////////////////////////////

void Snapshot::resetTransform(float x, float y, float z) {
    transform = &mTransformRoot;
    transform->loadTranslate(x, y, z);
}

///////////////////////////////////////////////////////////////////////////////
// Queries
///////////////////////////////////////////////////////////////////////////////

bool Snapshot::isIgnored() const {
    return invisible || empty;
}

}; // namespace uirenderer
}; // namespace android
+36 −102
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@
#include <utils/RefBase.h>
#include <ui/Region.h>

#include <SkCanvas.h>
#include <SkRegion.h>

#include "Layer.h"
#include "Matrix.h"
@@ -43,43 +43,12 @@ namespace uirenderer {
 */
class Snapshot: public LightRefBase<Snapshot> {
public:
    Snapshot(): flags(0), previous(NULL), layer(NULL), fbo(0), invisible(false), empty(false) {
        transform = &mTransformRoot;
        clipRect = &mClipRectRoot;
        region = NULL;
    }

    /**
     * Copies the specified snapshot/ The specified snapshot is stored as
     * the previous snapshot.
     */
    Snapshot(const sp<Snapshot>& s, int saveFlags):
            flags(0), previous(s), layer(NULL), fbo(s->fbo),
            invisible(s->invisible), empty(false), viewport(s->viewport), height(s->height) {
        if (saveFlags & SkCanvas::kMatrix_SaveFlag) {
            mTransformRoot.load(*s->transform);
            transform = &mTransformRoot;
        } else {
            transform = s->transform;
        }

        if (saveFlags & SkCanvas::kClip_SaveFlag) {
            mClipRectRoot.set(*s->clipRect);
            clipRect = &mClipRectRoot;
        } else {
            clipRect = s->clipRect;
        }

        if (s->flags & Snapshot::kFlagFboTarget) {
            flags |= Snapshot::kFlagFboTarget;
            region = s->region;
        } else {
            region = NULL;
        }
    }
    Snapshot();
    Snapshot(const sp<Snapshot>& s, int saveFlags);

    /**
     * Various flags set on #flags.
     * Various flags set on ::flags.
     */
    enum Flags {
        /**
@@ -115,87 +84,41 @@ public:
     * by this snapshot's trasnformation.
     */
    bool clip(float left, float top, float right, float bottom,
            SkRegion::Op op = SkRegion::kIntersect_Op) {
        Rect r(left, top, right, bottom);
        transform->mapRect(r);
        return clipTransformed(r, op);
    }
            SkRegion::Op op = SkRegion::kIntersect_Op);

    /**
     * Modifies the current clip with the new clip rectangle and
     * the specified operation. The specified rectangle is considered
     * already transformed.
     */
    bool clipTransformed(const Rect& r, SkRegion::Op op = SkRegion::kIntersect_Op) {
        bool clipped = false;

        // NOTE: The unimplemented operations require support for regions
        // Supporting regions would require using a stencil buffer instead
        // of the scissor. The stencil buffer itself is not too expensive
        // (memory cost excluded) but on fillrate limited devices, managing
        // the stencil might have a negative impact on the framerate.
        switch (op) {
            case SkRegion::kDifference_Op:
                break;
            case SkRegion::kIntersect_Op:
                clipped = clipRect->intersect(r);
                if (!clipped) {
                    clipRect->setEmpty();
                    clipped = true;
                }
                break;
            case SkRegion::kUnion_Op:
                clipped = clipRect->unionWith(r);
                break;
            case SkRegion::kXOR_Op:
                break;
            case SkRegion::kReverseDifference_Op:
                break;
            case SkRegion::kReplace_Op:
                clipRect->set(r);
                clipped = true;
                break;
        }

        if (clipped) {
            flags |= Snapshot::kFlagClipSet;
        }

        return clipped;
    }
    bool clipTransformed(const Rect& r, SkRegion::Op op = SkRegion::kIntersect_Op);

    /**
     * Sets the current clip.
     */
    void setClip(float left, float top, float right, float bottom) {
        clipRect->set(left, top, right, bottom);
        flags |= Snapshot::kFlagClipSet;
    }

    const Rect& getLocalClip() {
        mat4 inverse;
        inverse.loadInverse(*transform);

        mLocalClip.set(*clipRect);
        inverse.mapRect(mLocalClip);
    void setClip(float left, float top, float right, float bottom);

        return mLocalClip;
    }
    /**
     * Returns the current clip in local coordinates. The clip rect is
     * transformed by the inverse transform matrix.
     */
    const Rect& getLocalClip();

    void resetTransform(float x, float y, float z) {
        transform = &mTransformRoot;
        transform->loadTranslate(x, y, z);
    }
    /**
     * Resets the clip to the specified rect.
     */
    void resetClip(float left, float top, float right, float bottom);

    void resetClip(float left, float top, float right, float bottom) {
        clipRect = &mClipRectRoot;
        clipRect->set(left, top, right, bottom);
        flags |= Snapshot::kFlagClipSet;
    }
    /**
     * Resets the current transform to a pure 3D translation.
     */
    void resetTransform(float x, float y, float z);

    bool isIgnored() const {
        return invisible || empty;
    }
    /**
     * Indicates whether this snapshot should be ignored. A snapshot
     * is typicalled ignored if its layer is invisible or empty.
     */
    bool isIgnored() const;

    /**
     * Dirty flags.
@@ -209,6 +132,8 @@ public:

    /**
     * Only set when the flag kFlagIsLayer is set.
     *
     * This snapshot does not own the layer, this pointer must not be freed.
     */
    Layer* layer;

@@ -249,17 +174,26 @@ public:
    /**
     * Local transformation. Holds the current translation, scale and
     * rotation values.
     *
     * This is a reference to a matrix owned by this snapshot or another
     *  snapshot. This pointer must not be freed. See ::mTransformRoot.
     */
    mat4* transform;

    /**
     * Current clip region. The clip is stored in canvas-space coordinates,
     * (screen-space coordinates in the regular case.)
     *
     * This is a reference to a rect owned by this snapshot or another
     * snapshot. This pointer must not be freed. See ::mClipRectRoot.
     */
    Rect* clipRect;

    /**
     * The ancestor layer's dirty region.
     *
     * This is a reference to a region owned by a layer. This pointer must
     * not be freed.
     */
    Region* region;