/*
 * Copyright (C) 2010 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.
 */

#ifndef ANDROID_HWUI_OPENGL_RENDERER_H
#define ANDROID_HWUI_OPENGL_RENDERER_H

#include "CanvasState.h"
#include "Debug.h"
#include "Extensions.h"
#include "Matrix.h"
#include "Program.h"
#include "Rect.h"
#include "Snapshot.h"
#include "UvMapper.h"
#include "Vertex.h"
#include "Caches.h"
#include "utils/PaintUtils.h"

#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>

#include <SkBitmap.h>
#include <SkCanvas.h>
#include <SkColorFilter.h>
#include <SkMatrix.h>
#include <SkPaint.h>
#include <SkRegion.h>
#include <SkXfermode.h>

#include <utils/Blur.h>
#include <utils/Functor.h>
#include <utils/RefBase.h>
#include <utils/SortedVector.h>
#include <utils/Vector.h>

#include <cutils/compiler.h>

#include <androidfw/ResourceTypes.h>

class SkShader;

namespace android {
namespace uirenderer {

enum class DrawOpMode {
    kImmediate,
    kDefer,
    kFlush
};

class DeferredDisplayState;
struct Glop;
class RenderState;
class RenderNode;
class TextDrawFunctor;
class VertexBuffer;

enum StateDeferFlags {
    kStateDeferFlag_Draw = 0x1,
    kStateDeferFlag_Clip = 0x2
};

enum ClipSideFlags {
    kClipSide_None = 0x0,
    kClipSide_Left = 0x1,
    kClipSide_Top = 0x2,
    kClipSide_Right = 0x4,
    kClipSide_Bottom = 0x8,
    kClipSide_Full = 0xF,
    kClipSide_ConservativeFull = 0x1F
};

enum VertexBufferDisplayFlags {
    kVertexBuffer_Offset = 0x1,
    kVertexBuffer_ShadowInterp = 0x2,
};

/**
 * Defines additional transformation that should be applied by the model view matrix, beyond that of
 * the currentTransform()
 */
enum ModelViewMode {
    /**
     * Used when the model view should simply translate geometry passed to the shader. The resulting
     * matrix will be a simple translation.
     */
    kModelViewMode_Translate = 0,

    /**
     * Used when the model view should translate and scale geometry. The resulting matrix will be a
     * translation + scale. This is frequently used together with VBO 0, the (0,0,1,1) rect.
     */
    kModelViewMode_TranslateAndScale = 1,
};

///////////////////////////////////////////////////////////////////////////////
// Renderer
///////////////////////////////////////////////////////////////////////////////
/**
 * OpenGL Renderer implementation.
 */
class OpenGLRenderer : public CanvasStateClient {
public:
    OpenGLRenderer(RenderState& renderState);
    virtual ~OpenGLRenderer();

    /**
     * Sets the dimension of the underlying drawing surface. This method must
     * be called at least once every time the drawing surface changes size.
     *
     * @param width The width in pixels of the underlysing surface
     * @param height The height in pixels of the underlysing surface
     */
    void setViewport(int width, int height) { mState.setViewport(width, height); }

    void initProperties();
    void initLight(float lightRadius, uint8_t ambientShadowAlpha,
            uint8_t spotShadowAlpha);
    void setLightCenter(const Vector3& lightCenter);

    /*
     * Prepares the renderer to draw a frame. This method must be invoked
     * at the beginning of each frame. Only the specified rectangle of the
     * frame is assumed to be dirty. A clip will automatically be set to
     * the specified rectangle.
     *
     * @param opaque If true, the target surface is considered opaque
     *               and will not be cleared. If false, the target surface
     *               will be cleared
     */
    virtual void prepareDirty(float left, float top, float right, float bottom,
            bool opaque);

    /**
     * Prepares the renderer to draw a frame. This method must be invoked
     * at the beginning of each frame. When this method is invoked, the
     * entire drawing surface is assumed to be redrawn.
     *
     * @param opaque If true, the target surface is considered opaque
     *               and will not be cleared. If false, the target surface
     *               will be cleared
     */
    void prepare(bool opaque) {
        prepareDirty(0.0f, 0.0f, mState.getWidth(), mState.getHeight(), opaque);
    }

    /**
     * Indicates the end of a frame. This method must be invoked whenever
     * the caller is done rendering a frame.
     * Returns true if any drawing was done during the frame (the output
     * has changed / is "dirty" and should be displayed to the user).
     */
    virtual bool finish();

    void callDrawGLFunction(Functor* functor, Rect& dirty);

    void pushLayerUpdate(Layer* layer);
    void cancelLayerUpdate(Layer* layer);
    void flushLayerUpdates();
    void markLayersAsBuildLayers();

    virtual int saveLayer(float left, float top, float right, float bottom,
            const SkPaint* paint, int flags) {
        return saveLayer(left, top, right, bottom, paint, flags, nullptr);
    }

    // Specialized saveLayer implementation, which will pass the convexMask to an FBO layer, if
    // created, which will in turn clip to that mask when drawn back/restored.
    int saveLayer(float left, float top, float right, float bottom,
            const SkPaint* paint, int flags, const SkPath* convexMask);

    int saveLayerDeferred(float left, float top, float right, float bottom,
            const SkPaint* paint, int flags);

    void drawRenderNode(RenderNode* displayList, Rect& dirty, int32_t replayFlags = 1);
    void drawLayer(Layer* layer, float x, float y);
    void drawBitmap(const SkBitmap* bitmap, const SkPaint* paint);
    void drawBitmaps(const SkBitmap* bitmap, AssetAtlas::Entry* entry, int bitmapCount,
            TextureVertex* vertices, bool pureTranslate, const Rect& bounds, const SkPaint* paint);
    void drawBitmap(const SkBitmap* bitmap, Rect src, Rect dst,
            const SkPaint* paint);
    void drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
            const float* vertices, const int* colors, const SkPaint* paint);
    void drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry* entry,
            TextureVertex* vertices, uint32_t indexCount, const SkPaint* paint);
    void drawPatch(const SkBitmap* bitmap, const Patch* mesh, AssetAtlas::Entry* entry,
            float left, float top, float right, float bottom, const SkPaint* paint);
    void drawColor(int color, SkXfermode::Mode mode);
    void drawRect(float left, float top, float right, float bottom,
            const SkPaint* paint);
    void drawRoundRect(float left, float top, float right, float bottom,
            float rx, float ry, const SkPaint* paint);
    void drawCircle(float x, float y, float radius, const SkPaint* paint);
    void drawOval(float left, float top, float right, float bottom,
            const SkPaint* paint);
    void drawArc(float left, float top, float right, float bottom,
            float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint);
    void drawPath(const SkPath* path, const SkPaint* paint);
    void drawLines(const float* points, int count, const SkPaint* paint);
    void drawPoints(const float* points, int count, const SkPaint* paint);
    void drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path,
            float hOffset, float vOffset, const SkPaint* paint);
    void drawPosText(const char* text, int bytesCount, int count,
            const float* positions, const SkPaint* paint);
    void drawText(const char* text, int bytesCount, int count, float x, float y,
            const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds,
            DrawOpMode drawOpMode = DrawOpMode::kImmediate);
    void drawRects(const float* rects, int count, const SkPaint* paint);

    void drawShadow(float casterAlpha,
            const VertexBuffer* ambientShadowVertexBuffer,
            const VertexBuffer* spotShadowVertexBuffer);

    void setDrawFilter(SkDrawFilter* filter);

    /**
     * Store the current display state (most importantly, the current clip and transform), and
     * additionally map the state's bounds from local to window coordinates.
     *
     * Returns true if quick-rejected
     */
    bool storeDisplayState(DeferredDisplayState& state, int stateDeferFlags);
    void restoreDisplayState(const DeferredDisplayState& state, bool skipClipRestore = false);
    void setupMergedMultiDraw(const Rect* clipRect);

    bool isCurrentTransformSimple() {
        return currentTransform()->isSimple();
    }

    Caches& getCaches() {
        return mCaches;
    }

    RenderState& renderState() {
        return mRenderState;
    }

    int getViewportWidth() { return mState.getViewportWidth(); }
    int getViewportHeight() { return mState.getViewportHeight(); }

    /**
     * Scales the alpha on the current snapshot. This alpha value will be modulated
     * with other alpha values when drawing primitives.
     */
    void scaleAlpha(float alpha) { mState.scaleAlpha(alpha); }

    /**
     * Inserts a named event marker in the stream of GL commands.
     */
    void eventMark(const char* name) const;

    /**
     * Inserts a formatted event marker in the stream of GL commands.
     */
    void eventMarkDEBUG(const char *fmt, ...) const;

    /**
     * Inserts a named group marker in the stream of GL commands. This marker
     * can be used by tools to group commands into logical groups. A call to
     * this method must always be followed later on by a call to endMark().
     */
    void startMark(const char* name) const;

    /**
     * Closes the last group marker opened by startMark().
     */
    void endMark() const;

    /**
     * Gets the alpha and xfermode out of a paint object. If the paint is null
     * alpha will be 255 and the xfermode will be SRC_OVER. This method does
     * not multiply the paint's alpha by the current snapshot's alpha, and does
     * not replace the alpha with the overrideLayerAlpha
     *
     * @param paint The paint to extract values from
     * @param alpha Where to store the resulting alpha
     * @param mode Where to store the resulting xfermode
     */
    static inline void getAlphaAndModeDirect(const SkPaint* paint, int* alpha,
            SkXfermode::Mode* mode) {
        *mode = getXfermodeDirect(paint);
        *alpha = getAlphaDirect(paint);
    }

    static inline SkXfermode::Mode getXfermodeDirect(const SkPaint* paint) {
        if (!paint) return SkXfermode::kSrcOver_Mode;
        return PaintUtils::getXfermode(paint->getXfermode());
    }

    static inline int getAlphaDirect(const SkPaint* paint) {
        if (!paint) return 255;
        return paint->getAlpha();
    }

    struct TextShadow {
        SkScalar radius;
        float dx;
        float dy;
        SkColor color;
    };

    static inline bool getTextShadow(const SkPaint* paint, TextShadow* textShadow) {
        SkDrawLooper::BlurShadowRec blur;
        if (paint && paint->getLooper() && paint->getLooper()->asABlurShadow(&blur)) {
            if (textShadow) {
                textShadow->radius = Blur::convertSigmaToRadius(blur.fSigma);
                textShadow->dx = blur.fOffset.fX;
                textShadow->dy = blur.fOffset.fY;
                textShadow->color = blur.fColor;
            }
            return true;
        }
        return false;
    }

    static inline bool hasTextShadow(const SkPaint* paint) {
        return getTextShadow(paint, nullptr);
    }

    /**
     * Build the best transform to use to rasterize text given a full
     * transform matrix, and whether filteration is needed.
     *
     * Returns whether filtration is needed
     */
    bool findBestFontTransform(const mat4& transform, SkMatrix* outMatrix) const;

#if DEBUG_MERGE_BEHAVIOR
    void drawScreenSpaceColorRect(float left, float top, float right, float bottom, int color) {
        mCaches.setScissorEnabled(false);

        // should only be called outside of other draw ops, so stencil can only be in test state
        bool stencilWasEnabled = mCaches.stencil.isTestEnabled();
        mCaches.stencil.disable();

        drawColorRect(left, top, right, bottom, color, SkXfermode::kSrcOver_Mode, true);

        if (stencilWasEnabled) mCaches.stencil.enableTest();
        mDirty = true;
    }
#endif

    const Vector3& getLightCenter() const { return mState.currentLightCenter(); }
    float getLightRadius() const { return mLightRadius; }
    uint8_t getAmbientShadowAlpha() const { return mAmbientShadowAlpha; }
    uint8_t getSpotShadowAlpha() const { return mSpotShadowAlpha; }

    ///////////////////////////////////////////////////////////////////
    /// State manipulation

    int getSaveCount() const;
    int save(int flags);
    void restore();
    void restoreToCount(int saveCount);

    void getMatrix(SkMatrix* outMatrix) const { mState.getMatrix(outMatrix); }
    void setMatrix(const SkMatrix& matrix) { mState.setMatrix(matrix); }
    void concatMatrix(const SkMatrix& matrix) { mState.concatMatrix(matrix); }

    void translate(float dx, float dy, float dz = 0.0f);
    void rotate(float degrees);
    void scale(float sx, float sy);
    void skew(float sx, float sy);

    void setMatrix(const Matrix4& matrix); // internal only convenience method
    void concatMatrix(const Matrix4& matrix); // internal only convenience method

    const Rect& getLocalClipBounds() const { return mState.getLocalClipBounds(); }
    const Rect& getRenderTargetClipBounds() const { return mState.getRenderTargetClipBounds(); }
    bool quickRejectConservative(float left, float top,
            float right, float bottom) const {
        return mState.quickRejectConservative(left, top, right, bottom);
    }

    bool clipRect(float left, float top,
            float right, float bottom, SkRegion::Op op);
    bool clipPath(const SkPath* path, SkRegion::Op op);
    bool clipRegion(const SkRegion* region, SkRegion::Op op);

    /**
     * Does not support different clipping Ops (that is, every call to setClippingOutline is
     * effectively using SkRegion::kReplaceOp)
     *
     * The clipping outline is independent from the regular clip.
     */
    void setClippingOutline(LinearAllocator& allocator, const Outline* outline);
    void setClippingRoundRect(LinearAllocator& allocator,
            const Rect& rect, float radius, bool highPriority = true);
    void setProjectionPathMask(LinearAllocator& allocator, const SkPath* path);

    inline bool hasRectToRectTransform() const { return mState.hasRectToRectTransform(); }
    inline const mat4* currentTransform() const { return mState.currentTransform(); }

    ///////////////////////////////////////////////////////////////////
    /// CanvasStateClient interface

    virtual void onViewportInitialized() override;
    virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) override;
    virtual GLuint getTargetFbo() const override { return 0; }

    SkPath* allocPathForFrame() {
        std::unique_ptr<SkPath> path(new SkPath());
        SkPath* returnPath = path.get();
        mTempPaths.push_back(std::move(path));
        return returnPath;
    }

protected:
    /**
     * Perform the setup specific to a frame. This method does not
     * issue any OpenGL commands.
     */
    void setupFrameState(float left, float top, float right, float bottom, bool opaque);

    /**
     * Indicates the start of rendering. This method will setup the
     * initial OpenGL state (viewport, clearing the buffer, etc.)
     */
    void startFrame();

    /**
     * Clears the underlying surface if needed.
     */
    virtual void clear(float left, float top, float right, float bottom, bool opaque);

    /**
     * Call this method after updating a layer during a drawing pass.
     */
    void resumeAfterLayer();

    /**
     * This method is called whenever a stencil buffer is required. Subclasses
     * should override this method and call attachStencilBufferToLayer() on the
     * appropriate layer(s).
     */
    virtual void ensureStencilBuffer();

    /**
     * Obtains a stencil render buffer (allocating it if necessary) and
     * attaches it to the specified layer.
     */
    void attachStencilBufferToLayer(Layer* layer);

    /**
     * Draw a rectangle list. Currently only used for the the stencil buffer so that the stencil
     * will have a value of 'n' in every unclipped pixel, where 'n' is the number of rectangles
     * in the list.
     */
    void drawRectangleList(const RectangleList& rectangleList);

    bool quickRejectSetupScissor(float left, float top, float right, float bottom,
            const SkPaint* paint = nullptr);
    bool quickRejectSetupScissor(const Rect& bounds, const SkPaint* paint = nullptr) {
        return quickRejectSetupScissor(bounds.left, bounds.top,
                bounds.right, bounds.bottom, paint);
    }

    /**
     * Compose the layer defined in the current snapshot with the layer
     * defined by the previous snapshot.
     *
     * The current snapshot *must* be a layer (flag kFlagIsLayer set.)
     *
     * @param curent The current snapshot containing the layer to compose
     * @param previous The previous snapshot to compose the current layer with
     */
    virtual void composeLayer(const Snapshot& current, const Snapshot& previous);

    /**
     * Marks the specified region as dirty at the specified bounds.
     */
    void dirtyLayerUnchecked(Rect& bounds, Region* region);

    /**
     * Returns the region of the current layer.
     */
    virtual Region* getRegion() const {
        return mState.currentRegion();
    }

    /**
     * Indicates whether rendering is currently targeted at a layer.
     */
    virtual bool hasLayer() const {
        return (mState.currentFlags() & Snapshot::kFlagFboTarget) && mState.currentRegion();
    }

    /**
     * Renders the specified layer as a textured quad.
     *
     * @param layer The layer to render
     * @param rect The bounds of the layer
     */
    void drawTextureLayer(Layer* layer, const Rect& rect);

    /**
     * Gets the alpha and xfermode out of a paint object. If the paint is null
     * alpha will be 255 and the xfermode will be SRC_OVER. Accounts for snapshot alpha.
     *
     * @param paint The paint to extract values from
     * @param alpha Where to store the resulting alpha
     * @param mode Where to store the resulting xfermode
     */
    inline void getAlphaAndMode(const SkPaint* paint, int* alpha, SkXfermode::Mode* mode) const;

    /**
     * Gets the alpha from a layer, accounting for snapshot alpha
     *
     * @param layer The layer from which the alpha is extracted
     */
    inline float getLayerAlpha(const Layer* layer) const;

    /**
     * Set to true to suppress error checks at the end of a frame.
     */
    virtual bool suppressErrorChecks() const {
        return false;
    }

    CanvasState mState;
    Caches& mCaches;
    RenderState& mRenderState;

private:
    void renderGlop(const Glop& glop, bool clearLayer = true);

    /**
     * Discards the content of the framebuffer if supported by the driver.
     * This method should be called at the beginning of a frame to optimize
     * rendering on some tiler architectures.
     */
    void discardFramebuffer(float left, float top, float right, float bottom);

    /**
     * Tells the GPU what part of the screen is about to be redrawn.
     * This method will use the current layer space clip rect.
     * This method needs to be invoked every time getTargetFbo() is
     * bound again.
     */
    void startTilingCurrentClip(bool opaque = false, bool expand = false);

    /**
     * Tells the GPU what part of the screen is about to be redrawn.
     * This method needs to be invoked every time getTargetFbo() is
     * bound again.
     */
    void startTiling(const Rect& clip, int windowHeight, bool opaque = false, bool expand = false);

    /**
     * Tells the GPU that we are done drawing the frame or that we
     * are switching to another render target.
     */
    void endTiling();

    /**
     * Sets the clipping rectangle using glScissor. The clip is defined by
     * the current snapshot's clipRect member.
     */
    void setScissorFromClip();

    /**
     * Sets the clipping region using the stencil buffer. The clip region
     * is defined by the current snapshot's clipRegion member.
     */
    void setStencilFromClip();

    /**
     * Given the local bounds of the layer, calculates ...
     */
    void calculateLayerBoundsAndClip(Rect& bounds, Rect& clip, bool fboLayer);

    /**
     * Given the local bounds + clip of the layer, updates current snapshot's empty/invisible
     */
    void updateSnapshotIgnoreForLayer(const Rect& bounds, const Rect& clip,
            bool fboLayer, int alpha);

    /**
     * Creates a new layer stored in the specified snapshot.
     *
     * @param snapshot The snapshot associated with the new layer
     * @param left The left coordinate of the layer
     * @param top The top coordinate of the layer
     * @param right The right coordinate of the layer
     * @param bottom The bottom coordinate of the layer
     * @param alpha The translucency of the layer
     * @param mode The blending mode of the layer
     * @param flags The layer save flags
     * @param mask A mask to use when drawing the layer back, may be empty
     *
     * @return True if the layer was successfully created, false otherwise
     */
    bool createLayer(float left, float top, float right, float bottom,
            const SkPaint* paint, int flags, const SkPath* convexMask);

    /**
     * Creates a new layer stored in the specified snapshot as an FBO.
     *
     * @param layer The layer to store as an FBO
     * @param snapshot The snapshot associated with the new layer
     * @param bounds The bounds of the layer
     */
    bool createFboLayer(Layer* layer, Rect& bounds, Rect& clip);

    /**
     * Compose the specified layer as a region.
     *
     * @param layer The layer to compose
     * @param rect The layer's bounds
     */
    void composeLayerRegion(Layer* layer, const Rect& rect);

    /**
     * Restores the content in layer to the screen, swapping the blend mode,
     * specifically used in the restore() of a saveLayerAlpha().
     *
     * This allows e.g. a layer that would have been drawn on top of existing content (with SrcOver)
     * to be drawn underneath.
     *
     * This will always ignore the canvas transform.
     */
    void composeLayerRectSwapped(Layer* layer, const Rect& rect);

    /**
     * Draws the content in layer to the screen.
     */
    void composeLayerRect(Layer* layer, const Rect& rect);

    /**
     * Clears all the regions corresponding to the current list of layers.
     * This method MUST be invoked before any drawing operation.
     */
    void clearLayerRegions();

    /**
     * Mark the layer as dirty at the specified coordinates. The coordinates
     * are transformed with the supplied matrix.
     */
    void dirtyLayer(const float left, const float top,
            const float right, const float bottom, const Matrix4& transform);

    /**
     * Mark the layer as dirty at the specified coordinates.
     */
    void dirtyLayer(const float left, const float top,
            const float right, const float bottom);

    /**
     * Draws a colored rectangle with the specified color. The specified coordinates
     * are transformed by the current snapshot's transform matrix unless specified
     * otherwise.
     *
     * @param left The left coordinate of the rectangle
     * @param top The top coordinate of the rectangle
     * @param right The right coordinate of the rectangle
     * @param bottom The bottom coordinate of the rectangle
     * @param paint The paint containing the color, blending mode, etc.
     * @param ignoreTransform True if the current transform should be ignored
     */
    void drawColorRect(float left, float top, float right, float bottom,
            const SkPaint* paint, bool ignoreTransform = false);

    /**
     * Draws a series of colored rectangles with the specified color. The specified
     * coordinates are transformed by the current snapshot's transform matrix unless
     * specified otherwise.
     *
     * @param rects A list of rectangles, 4 floats (left, top, right, bottom)
     *              per rectangle
     * @param paint The paint containing the color, blending mode, etc.
     * @param ignoreTransform True if the current transform should be ignored
     * @param dirty True if calling this method should dirty the current layer
     * @param clip True if the rects should be clipped, false otherwise
     */
    void drawColorRects(const float* rects, int count, const SkPaint* paint,
            bool ignoreTransform = false, bool dirty = true, bool clip = true);

    /**
     * Draws the shape represented by the specified path texture.
     * This method invokes drawPathTexture() but takes into account
     * the extra left/top offset and the texture offset to correctly
     * position the final shape.
     *
     * @param left The left coordinate of the shape to render
     * @param top The top coordinate of the shape to render
     * @param texture The texture reprsenting the shape
     * @param paint The paint to draw the shape with
     */
    void drawShape(float left, float top, PathTexture* texture, const SkPaint* paint);

    /**
     * Renders a strip of polygons with the specified paint, used for tessellated geometry.
     *
     * @param vertexBuffer The VertexBuffer to be drawn
     * @param paint The paint to render with
     * @param flags flags with which to draw
     */
    void drawVertexBuffer(float translateX, float translateY, const VertexBuffer& vertexBuffer,
            const SkPaint* paint, int flags = 0);

    /**
     * Convenience for translating method
     */
    void drawVertexBuffer(const VertexBuffer& vertexBuffer,
            const SkPaint* paint, int flags = 0) {
        drawVertexBuffer(0.0f, 0.0f, vertexBuffer, paint, flags);
    }

    /**
     * Renders the convex hull defined by the specified path as a strip of polygons.
     *
     * @param path The hull of the path to draw
     * @param paint The paint to render with
     */
    void drawConvexPath(const SkPath& path, const SkPaint* paint);

    /**
     * Draws text underline and strike-through if needed.
     *
     * @param text The text to decor
     * @param bytesCount The number of bytes in the text
     * @param totalAdvance The total advance in pixels, defines underline/strikethrough length
     * @param x The x coordinate where the text will be drawn
     * @param y The y coordinate where the text will be drawn
     * @param paint The paint to draw the text with
     */
    void drawTextDecorations(float totalAdvance, float x, float y, const SkPaint* paint);

   /**
     * Draws shadow layer on text (with optional positions).
     *
     * @param paint The paint to draw the shadow with
     * @param text The text to draw
     * @param bytesCount The number of bytes in the text
     * @param count The number of glyphs in the text
     * @param positions The x, y positions of individual glyphs (or NULL)
     * @param fontRenderer The font renderer object
     * @param alpha The alpha value for drawing the shadow
     * @param x The x coordinate where the shadow will be drawn
     * @param y The y coordinate where the shadow will be drawn
     */
    void drawTextShadow(const SkPaint* paint, const char* text, int bytesCount, int count,
            const float* positions, FontRenderer& fontRenderer, int alpha,
            float x, float y);

    /**
     * Draws a path texture. Path textures are alpha8 bitmaps that need special
     * compositing to apply colors/filters/etc.
     *
     * @param texture The texture to render
     * @param x The x coordinate where the texture will be drawn
     * @param y The y coordinate where the texture will be drawn
     * @param paint The paint to draw the texture with
     */
     void drawPathTexture(PathTexture* texture, float x, float y, const SkPaint* paint);

    /**
     * Resets the texture coordinates stored in mMeshVertices. Setting the values
     * back to default is achieved by calling:
     *
     * resetDrawTextureTexCoords(0.0f, 0.0f, 1.0f, 1.0f);
     *
     * @param u1 The left coordinate of the texture
     * @param v1 The bottom coordinate of the texture
     * @param u2 The right coordinate of the texture
     * @param v2 The top coordinate of the texture
     */
    void resetDrawTextureTexCoords(float u1, float v1, float u2, float v2);

    /**
     * Returns true if the specified paint will draw invisible text.
     */
    bool canSkipText(const SkPaint* paint) const;

    bool updateLayer(Layer* layer, bool inFrame);
    void updateLayers();
    void flushLayers();

#if DEBUG_LAYERS_AS_REGIONS
    /**
     * Renders the specified region as a series of rectangles. This method
     * is used for debugging only.
     */
    void drawRegionRectsDebug(const Region& region);
#endif

    /**
     * Renders the specified region as a series of rectangles. The region
     * must be in screen-space coordinates.
     */
    void drawRegionRects(const SkRegion& region, const SkPaint& paint, bool dirty = false);

    /**
     * Draws the current clip region if any. Only when DEBUG_CLIP_REGIONS
     * is turned on.
     */
    void debugClip();

    void debugOverdraw(bool enable, bool clear);
    void renderOverdraw();
    void countOverdraw();

    /**
     * Should be invoked every time the glScissor is modified.
     */
    inline void dirtyClip() { mState.setDirtyClip(true); }

    inline const UvMapper& getMapper(const Texture* texture) {
        return texture && texture->uvMapper ? *texture->uvMapper : mUvMapper;
    }

    /**
     * Returns a texture object for the specified bitmap. The texture can
     * come from the texture cache or an atlas. If this method returns
     * NULL, the texture could not be found and/or allocated.
     */
    Texture* getTexture(const SkBitmap* bitmap);

    bool reportAndClearDirty() { bool ret = mDirty; mDirty = false; return ret; }
    inline Snapshot* writableSnapshot() { return mState.writableSnapshot(); }
    inline const Snapshot* currentSnapshot() const { return mState.currentSnapshot(); }

    // State used to define the clipping region
    Rect mTilingClip;
    // Is the target render surface opaque
    bool mOpaque;
    // Is a frame currently being rendered
    bool mFrameStarted;

    // Default UV mapper
    const UvMapper mUvMapper;

    // List of rectangles to clear after saveLayer() is invoked
    std::vector<Rect> mLayers;
    // List of layers to update at the beginning of a frame
    Vector< sp<Layer> > mLayerUpdates;

    // See PROPERTY_DISABLE_SCISSOR_OPTIMIZATION in
    // Properties.h
    bool mScissorOptimizationDisabled;

    // No-ops start/endTiling when set
    bool mSuppressTiling;
    bool mFirstFrameAfterResize;

    bool mSkipOutlineClip;

    // True if anything has been drawn since the last call to
    // reportAndClearDirty()
    bool mDirty;

    // Lighting + shadows
    Vector3 mLightCenter;
    float mLightRadius;
    uint8_t mAmbientShadowAlpha;
    uint8_t mSpotShadowAlpha;

    // Paths kept alive for the duration of the frame
    std::vector<std::unique_ptr<SkPath>> mTempPaths;

    friend class Layer;
    friend class TextDrawFunctor;
    friend class DrawBitmapOp;
    friend class DrawPatchOp;

}; // class OpenGLRenderer

}; // namespace uirenderer
}; // namespace android

#endif // ANDROID_HWUI_OPENGL_RENDERER_H
