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

Commit 4aa90573 authored by Romain Guy's avatar Romain Guy
Browse files

Adding display lists to the GL renderer (checkpoint.)

Change-Id: Iaa49757600a53b39369dbb23f8c3feab282518e6
parent cc64c5db
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -241,7 +241,8 @@ static void android_view_GLES20Canvas_drawPatch(JNIEnv* env, jobject canvas,
    Res_png_9patch* patch = reinterpret_cast<Res_png_9patch*>(storage);
    Res_png_9patch::deserialize(patch);

    renderer->drawPatch(bitmap, patch, left, top, right, bottom, paint);
    renderer->drawPatch(bitmap, &patch->xDivs[0], &patch->yDivs[0],
            patch->numXDivs, patch->numYDivs, left, top, right, bottom, paint);

    env->ReleaseByteArrayElements(chunks, storage, 0);
}
+5 −5
Original line number Diff line number Diff line
@@ -227,7 +227,7 @@

    <style name="Widget.AbsListView">
        <item name="android:scrollbars">vertical</item>
        <item name="android:fadingEdge">vertical</item>
        <item name="android:fadingEdge">none</item>
    </style>

    <style name="Widget.GestureOverlayView">
@@ -495,12 +495,12 @@

    <style name="Widget.ScrollView">
        <item name="android:scrollbars">vertical</item>
        <item name="android:fadingEdge">vertical</item>
        <item name="android:fadingEdge">none</item>
    </style>

    <style name="Widget.HorizontalScrollView">
        <item name="android:scrollbars">horizontal</item>
        <item name="android:fadingEdge">horizontal</item>
        <item name="android:fadingEdge">none</item>
    </style>

    <style name="Widget.ListView" parent="Widget.AbsListView">
@@ -523,7 +523,7 @@
    <style name="Widget.ListView.Menu">
		<item name="android:cacheColorHint">@null</item>
        <item name="android:scrollbars">vertical</item>
        <item name="android:fadingEdge">vertical</item>
        <item name="android:fadingEdge">none</item>
        <item name="listSelector">@android:drawable/menu_selector</item>
        <!-- Light background for the list in menus, so the divider for bright themes -->
        <item name="android:divider">@android:drawable/divider_horizontal_dark</item>
@@ -556,7 +556,7 @@
    </style>

    <style name="Widget.Gallery">
        <item name="android:fadingEdge">horizontal</item>
        <item name="android:fadingEdge">none</item>
        <item name="android:gravity">center_vertical</item>
        <item name="android:spacing">-20dip</item>
        <item name="android:unselectedAlpha">0.85</item>
+1 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@ include $(CLEAR_VARS)
# defined in the current device/board configuration
ifeq ($(USE_OPENGL_RENDERER),true)
	LOCAL_SRC_FILES:= \
		DisplayListRenderer.cpp \
		FboCache.cpp \
		FontRenderer.cpp \
		GammaFontRenderer.cpp \
+302 −0
Original line number Diff line number Diff line
/*
 * 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.
 */

#define LOG_TAG "OpenGLRenderer"

#include "DisplayListRenderer.h"

namespace android {
namespace uirenderer {

///////////////////////////////////////////////////////////////////////////////
// Base structure
///////////////////////////////////////////////////////////////////////////////

DisplayListRenderer::DisplayListRenderer():
        mHeap(HEAP_BLOCK_SIZE), mWriter(MIN_WRITER_SIZE) {
    mBitmapIndex = mMatrixIndex = mPaintIndex = 1;
    mPathHeap = NULL;
}

DisplayListRenderer::~DisplayListRenderer() {
    reset();
}

void DisplayListRenderer::reset() {
    if (mPathHeap) {
        mPathHeap->unref();
        mPathHeap = NULL;
    }

    mBitmaps.reset();
    mMatrices.reset();
    mPaints.reset();

    mWriter.reset();
    mHeap.reset();

    mRCRecorder.reset();
    mTFRecorder.reset();
}

///////////////////////////////////////////////////////////////////////////////
// Operations
///////////////////////////////////////////////////////////////////////////////

void DisplayListRenderer::acquireContext() {
    addOp(AcquireContext);
    OpenGLRenderer::acquireContext();
}

void DisplayListRenderer::releaseContext() {
    addOp(ReleaseContext);
    OpenGLRenderer::releaseContext();
}

int DisplayListRenderer::save(int flags) {
    addOp(Save);
    addInt(flags);
    return OpenGLRenderer::save(flags);
}

void DisplayListRenderer::restore() {
    addOp(Restore);
    OpenGLRenderer::restore();
}

void DisplayListRenderer::restoreToCount(int saveCount) {
    addOp(RestoreToCount);
    addInt(saveCount);
    OpenGLRenderer::restoreToCount(saveCount);
}

int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom,
        const SkPaint* p, int flags) {
    addOp(SaveLayer);
    addBounds(left, top, right, bottom);
    addPaint(p);
    addInt(flags);
    return OpenGLRenderer::saveLayer(left, top, right, bottom, p, flags);
}

void DisplayListRenderer::translate(float dx, float dy) {
    addOp(Translate);
    addPoint(dx, dy);
    OpenGLRenderer::translate(dx, dy);
}

void DisplayListRenderer::rotate(float degrees) {
    addOp(Rotate);
    addFloat(degrees);
    OpenGLRenderer::rotate(degrees);
}

void DisplayListRenderer::scale(float sx, float sy) {
    addOp(Scale);
    addPoint(sx, sy);
    OpenGLRenderer::scale(sx, sy);
}

void DisplayListRenderer::setMatrix(SkMatrix* matrix) {
    addOp(SetMatrix);
    addMatrix(matrix);
    OpenGLRenderer::setMatrix(matrix);
}

void DisplayListRenderer::concatMatrix(SkMatrix* matrix) {
    addOp(ConcatMatrix);
    addMatrix(matrix);
    OpenGLRenderer::concatMatrix(matrix);
}

bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom,
        SkRegion::Op op) {
    addOp(ClipRect);
    addBounds(left, top, right, bottom);
    addInt(op);
    return OpenGLRenderer::clipRect(left, top, right, bottom, op);
}

void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top,
        const SkPaint* paint) {
    addOp(DrawBitmap);
    addBitmap(bitmap);
    addPoint(left, top);
    addPaint(paint);
    OpenGLRenderer::drawBitmap(bitmap, left, top, paint);
}

void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, const SkMatrix* matrix,
        const SkPaint* paint) {
    addOp(DrawBitmapMatrix);
    addBitmap(bitmap);
    addMatrix(matrix);
    addPaint(paint);
    OpenGLRenderer::drawBitmap(bitmap, matrix, paint);
}

void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
        float srcRight, float srcBottom, float dstLeft, float dstTop,
        float dstRight, float dstBottom, const SkPaint* paint) {
    addOp(DrawBitmapRect);
    addBitmap(bitmap);
    addBounds(srcLeft, srcTop, srcRight, srcBottom);
    addBounds(dstLeft, dstTop, dstRight, dstBottom);
    addPaint(paint);
    OpenGLRenderer::drawBitmap(bitmap, srcLeft, srcTop, srcRight, srcBottom,
            dstLeft, dstTop, dstRight, dstBottom, paint);
}

void DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
        uint32_t width, uint32_t height, float left, float top, float right, float bottom,
        const SkPaint* paint) {
    addOp(DrawPatch);
    addBitmap(bitmap);
    addInts(xDivs, width);
    addInts(yDivs, height);
    addBounds(left, top, right, bottom);
    addPaint(paint);
    OpenGLRenderer::drawPatch(bitmap, xDivs, yDivs, width, height,
            left, top, right, bottom, paint);
}

void DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) {
    addOp(DrawColor);
    addInt(color);
    addInt(mode);
    OpenGLRenderer::drawColor(color, mode);
}

void DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
        const SkPaint* paint) {
    addOp(DrawRect);
    addBounds(left, top, right, bottom);
    addPaint(paint);
    OpenGLRenderer::drawRect(left, top, right, bottom, paint);
}

void DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
    addOp(DrawPath);
    addPath(path);
    addPaint(paint);
    OpenGLRenderer::drawPath(path, paint);
}

void DisplayListRenderer::drawLines(float* points, int count, const SkPaint* paint) {
    addOp(DrawLines);
    addFloats(points, count);
    addPaint(paint);
    OpenGLRenderer::drawLines(points, count, paint);
}

void DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
        float x, float y, SkPaint* paint) {
    addOp(DrawText);
    addText(text, bytesCount);
    addInt(count);
    addPoint(x, y);
    addPaint(paint);
    OpenGLRenderer::drawText(text, bytesCount, count, x, y, paint);
}

void DisplayListRenderer::resetShader() {
    addOp(ResetShader);
    OpenGLRenderer::resetShader();
}

void DisplayListRenderer::setupShader(SkiaShader* shader) {
    // TODO: Implement
    OpenGLRenderer::setupShader(shader);
}

void DisplayListRenderer::resetColorFilter() {
    addOp(ResetColorFilter);
    OpenGLRenderer::resetColorFilter();
}

void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) {
    // TODO: Implement
    OpenGLRenderer::setupColorFilter(filter);
}

void DisplayListRenderer::resetShadow() {
    addOp(ResetShadow);
    OpenGLRenderer::resetShadow();
}

void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) {
    addOp(SetupShadow);
    addFloat(radius);
    addPoint(dx, dy);
    addInt(color);
    OpenGLRenderer::setupShadow(radius, dx, dy, color);
}

///////////////////////////////////////////////////////////////////////////////
// Recording management
///////////////////////////////////////////////////////////////////////////////

int DisplayListRenderer::find(SkTDArray<const SkFlatPaint*>& paints, const SkPaint* paint) {
    if (paint == NULL) {
        return 0;
    }

    SkFlatPaint* flat = SkFlatPaint::Flatten(&mHeap, *paint, mPaintIndex,
            &mRCRecorder, &mTFRecorder);
    int index = SkTSearch<SkFlatData>((const SkFlatData**) paints.begin(),
            paints.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare);
    if (index >= 0) {
        (void) mHeap.unalloc(flat);
        return paints[index]->index();
    }

    index = ~index;
    *paints.insert(index) = flat;
    return mPaintIndex++;
}

int DisplayListRenderer::find(SkTDArray<const SkFlatMatrix*>& matrices, const SkMatrix* matrix) {
    if (matrix == NULL) {
        return 0;
    }

    SkFlatMatrix* flat = SkFlatMatrix::Flatten(&mHeap, *matrix, mMatrixIndex);
    int index = SkTSearch<SkFlatData>((const SkFlatData**) matrices.begin(),
            matrices.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare);
    if (index >= 0) {
        (void) mHeap.unalloc(flat);
        return matrices[index]->index();
    }
    index = ~index;
    *matrices.insert(index) = flat;
    return mMatrixIndex++;
}

int DisplayListRenderer::find(SkTDArray<const SkFlatBitmap*>& bitmaps, const SkBitmap& bitmap) {
    SkFlatBitmap* flat = SkFlatBitmap::Flatten(&mHeap, bitmap, mBitmapIndex, &mRCRecorder);
    int index = SkTSearch<SkFlatData>((const SkFlatData**) bitmaps.begin(),
            bitmaps.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare);
    if (index >= 0) {
        (void) mHeap.unalloc(flat);
        return bitmaps[index]->index();
    }
    index = ~index;
    *bitmaps.insert(index) = flat;
    return mBitmapIndex++;
}

}; // namespace uirenderer
}; // namespace android
+281 −0
Original line number Diff line number Diff line
/*
 * 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_UI_DISPLAY_LIST_RENDERER_H
#define ANDROID_UI_DISPLAY_LIST_RENDERER_H

#include <SkChunkAlloc.h>
#include <SkFlattenable.h>
#include <SkMatrix.h>
#include <SkPaint.h>
#include <SkPath.h>
#include <SkPictureFlat.h>
#include <SkRefCnt.h>
#include <SkTDArray.h>
#include <SkTSearch.h>

#include "OpenGLRenderer.h"

namespace android {
namespace uirenderer {

///////////////////////////////////////////////////////////////////////////////
// Defines
///////////////////////////////////////////////////////////////////////////////

#define MIN_WRITER_SIZE 16384
#define HEAP_BLOCK_SIZE 4096

///////////////////////////////////////////////////////////////////////////////
// Helpers
///////////////////////////////////////////////////////////////////////////////

class PathHeap: public SkRefCnt {
public:
    PathHeap(): mHeap(64 * sizeof(SkPath)) {
    };

    PathHeap(SkFlattenableReadBuffer& buffer): mHeap(64 * sizeof(SkPath)) {
        int count = buffer.readS32();

        mPaths.setCount(count);
        SkPath** ptr = mPaths.begin();
        SkPath* p = (SkPath*) mHeap.allocThrow(count * sizeof(SkPath));

        for (int i = 0; i < count; i++) {
            new (p) SkPath;
            p->unflatten(buffer);
            *ptr++ = p;
            p++;
        }
    }

    ~PathHeap() {
        SkPath** iter = mPaths.begin();
        SkPath** stop = mPaths.end();
        while (iter < stop) {
            (*iter)->~SkPath();
            iter++;
        }
    }

    int append(const SkPath& path) {
        SkPath* p = (SkPath*) mHeap.allocThrow(sizeof(SkPath));
        new (p) SkPath(path);
        *mPaths.append() = p;
        return mPaths.count();
    }

    int count() const { return mPaths.count(); }

    const SkPath& operator[](int index) const {
        return *mPaths[index];
    }

    void flatten(SkFlattenableWriteBuffer& buffer) const {
        int count = mPaths.count();

        buffer.write32(count);
        SkPath** iter = mPaths.begin();
        SkPath** stop = mPaths.end();
        while (iter < stop) {
            (*iter)->flatten(buffer);
            iter++;
        }
    }

private:
    SkChunkAlloc mHeap;
    SkTDArray<SkPath*> mPaths;
};

///////////////////////////////////////////////////////////////////////////////
// Renderer
///////////////////////////////////////////////////////////////////////////////

/**
 * Records drawing commands in a display list for latter playback.
 */
class DisplayListRenderer: public OpenGLRenderer {
public:
    DisplayListRenderer();
    ~DisplayListRenderer();

    enum Op {
        AcquireContext,
        ReleaseContext,
        Save,
        Restore,
        RestoreToCount,
        SaveLayer,
        SaveLayerAlpha,
        Translate,
        Rotate,
        Scale,
        SetMatrix,
        ConcatMatrix,
        ClipRect,
        DrawBitmap,
        DrawBitmapMatrix,
        DrawBitmapRect,
        DrawPatch,
        DrawColor,
        DrawRect,
        DrawPath,
        DrawLines,
        DrawText,
        ResetShader,
        SetupShader,
        ResetColorFilter,
        SetupColorFilter,
        ResetShadow,
        SetupShadow
    };

    void acquireContext();
    void releaseContext();

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

    int saveLayer(float left, float top, float right, float bottom,
            const SkPaint* p, int flags);

    void translate(float dx, float dy);
    void rotate(float degrees);
    void scale(float sx, float sy);

    void setMatrix(SkMatrix* matrix);
    void concatMatrix(SkMatrix* matrix);

    bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);

    void drawBitmap(SkBitmap* bitmap, float left, float top, const SkPaint* paint);
    void drawBitmap(SkBitmap* bitmap, const SkMatrix* matrix, const SkPaint* paint);
    void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
            float srcRight, float srcBottom, float dstLeft, float dstTop,
            float dstRight, float dstBottom, const SkPaint* paint);
    void drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
            uint32_t width, uint32_t height, 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 drawPath(SkPath* path, SkPaint* paint);
    void drawLines(float* points, int count, const SkPaint* paint);
    void drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint);

    void resetShader();
    void setupShader(SkiaShader* shader);

    void resetColorFilter();
    void setupColorFilter(SkiaColorFilter* filter);

    void resetShadow();
    void setupShadow(float radius, float dx, float dy, int color);

    void reset();

private:
    inline void addOp(Op drawOp) {
        mWriter.writeInt(drawOp);
    }

    inline void addInt(int value) {
        mWriter.writeInt(value);
    }

    void addInts(const int32_t* values, uint32_t count) {
        for (uint32_t i = 0; i < count; i++) {
            mWriter.writeInt(values[i]);
        }
    }

    inline void addFloat(float value) {
        mWriter.writeScalar(value);
    }

    void addFloats(const float* values, int count) {
        for (int i = 0; i < count; i++) {
            mWriter.writeScalar(values[i]);
        }
    }

    inline void addPoint(float x, float y) {
        mWriter.writeScalar(x);
        mWriter.writeScalar(y);
    }

    inline void addBounds(float left, float top, float right, float bottom) {
        mWriter.writeScalar(left);
        mWriter.writeScalar(top);
        mWriter.writeScalar(right);
        mWriter.writeScalar(bottom);
    }

    inline void addText(const void* text, size_t byteLength) {
        mWriter.writeInt(byteLength);
        mWriter.writePad(text, byteLength);
    }

    inline void addPath(const SkPath* path) {
        if (mPathHeap == NULL) {
            mPathHeap = new PathHeap();
        }
        addInt(mPathHeap->append(*path));
    }

    int find(SkTDArray<const SkFlatPaint*>& paints, const SkPaint* paint);

    inline void addPaint(const SkPaint* paint) {
        addInt(find(mPaints, paint));
    }

    int find(SkTDArray<const SkFlatMatrix*>& matrices, const SkMatrix* matrix);

    inline void addMatrix(const SkMatrix* matrix) {
        addInt(find(mMatrices, matrix));
    }

    int find(SkTDArray<const SkFlatBitmap*>& bitmaps, const SkBitmap& bitmap);

    inline void addBitmap(const SkBitmap* bitmap) {
        addInt(find(mBitmaps, *bitmap));
    }

    SkChunkAlloc mHeap;

    int mBitmapIndex;
    SkTDArray<const SkFlatBitmap*> mBitmaps;

    int mMatrixIndex;
    SkTDArray<const SkFlatMatrix*> mMatrices;

    int mPaintIndex;
    SkTDArray<const SkFlatPaint*> mPaints;

    PathHeap* mPathHeap;
    SkWriter32 mWriter;

    SkRefCntRecorder mRCRecorder;
    SkRefCntRecorder mTFRecorder;

}; // class DisplayListRenderer

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

#endif // ANDROID_UI_DISPLAY_LIST_RENDERER_H
Loading