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

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

Merge "Adding display lists to the GL renderer (checkpoint.)"

parents 098e0edb 4aa90573
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