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

Commit bb9524b6 authored by Romain Guy's avatar Romain Guy
Browse files

Add implementations for clipRect(), save() and restore().

The current implementation of clipRect() does not apply local transformations
before setting the new clip.

Change-Id: I5997871bb638dfcd1a8ef96354846af52427e445
parent 03f02927
Loading
Loading
Loading
Loading
+24 −21
Original line number Diff line number Diff line
@@ -137,10 +137,11 @@ class GLES20Canvas extends Canvas {

    @Override
    public boolean clipRect(float left, float top, float right, float bottom) {
        // TODO: Implement
        return false;
        return nClipRect(mRenderer, left, top, right, bottom);
    }
    
    private native boolean nClipRect(int renderer, float left, float top, float right, float bottom);

    @Override
    public boolean clipRect(float left, float top, float right, float bottom, Region.Op op) {
        throw new UnsupportedOperationException();
@@ -148,14 +149,14 @@ class GLES20Canvas extends Canvas {

    @Override
    public boolean clipRect(int left, int top, int right, int bottom) {
        // TODO: Implement
        return false;        
        return nClipRect(mRenderer, left, top, right, bottom);        
    }
    
    private native boolean nClipRect(int renderer, int left, int top, int right, int bottom);

    @Override
    public boolean clipRect(Rect rect) {
        // TODO: Implement
        return false;        
        return clipRect(rect.left, rect.top, rect.right, rect.bottom);        
    }

    @Override
@@ -165,8 +166,7 @@ class GLES20Canvas extends Canvas {

    @Override
    public boolean clipRect(RectF rect) {
        // TODO: Implement
        return false;        
        return clipRect(rect.left, rect.top, rect.right, rect.bottom);
    }

    @Override
@@ -198,14 +198,12 @@ class GLES20Canvas extends Canvas {

    @Override
    public boolean quickReject(Path path, EdgeType type) {
        // TODO: Implement
        return false;
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean quickReject(RectF rect, EdgeType type) {
        // TODO: Implement
        return false;
        return quickReject(rect.left, rect.top, rect.right, rect.bottom, type);
    }

    ///////////////////////////////////////////////////////////////////////////
@@ -254,16 +252,16 @@ class GLES20Canvas extends Canvas {

    @Override
    public int save() {
        // TODO: Implement
        return 0;
        return nSave(mRenderer, 0);
    }
    
    @Override
    public int save(int saveFlags) {
        // TODO: Implement
        return 0;
        return nSave(mRenderer, saveFlags);
    }

    private native int nSave(int renderer, int flags);
    
    @Override
    public int saveLayer(RectF bounds, Paint paint, int saveFlags) {
        // TODO: Implement
@@ -292,20 +290,25 @@ class GLES20Canvas extends Canvas {

    @Override
    public void restore() {
        // TODO: Implement
        nRestore(mRenderer);
    }
    
    private native void nRestore(int renderer);

    @Override
    public void restoreToCount(int saveCount) {
        // TODO: Implement
        nRestoreToCount(mRenderer, saveCount);
    }

    private native void nRestoreToCount(int renderer, int saveCount);
    
    @Override
    public int getSaveCount() {
        // TODO: Implement
        return 0;
        return nGetSaveCount(mRenderer);
    }
    
    private native int nGetSaveCount(int renderer);

    ///////////////////////////////////////////////////////////////////////////
    // Filtering
    ///////////////////////////////////////////////////////////////////////////
+54 −6
Original line number Diff line number Diff line
@@ -54,7 +54,47 @@ static void android_view_GLES20Renderer_prepare(JNIEnv* env, jobject canvas, jin
}

// ----------------------------------------------------------------------------
// Draw color
// State
// ----------------------------------------------------------------------------

static jint android_view_GLES20Renderer_save(JNIEnv* env, jobject canvas, jint renderer,
        jint flags) {

    return UI->save(flags);
}

static jint android_view_GLES20Renderer_getSaveCount(JNIEnv* env, jobject canvas, jint renderer) {
    return UI->getSaveCount();
}

static void android_view_GLES20Renderer_restore(JNIEnv* env, jobject canvas, jint renderer) {
    UI->restore();
}

static void android_view_GLES20Renderer_restoreToCount(JNIEnv* env, jobject canvas, jint renderer,
        jint saveCount) {

    UI->restoreToCount(saveCount);
}

// ----------------------------------------------------------------------------
// Clipping
// ----------------------------------------------------------------------------

static bool android_view_GLES20Renderer_clipRectF(JNIEnv* env, jobject canvas, jint renderer,
        jfloat left, jfloat top, jfloat right, jfloat bottom) {

    return UI->clipRect(left, top, right, bottom);
}

static bool android_view_GLES20Renderer_clipRect(JNIEnv* env, jobject canvas, jint renderer,
        jint left, jint top, jint right, jint bottom) {

    return UI->clipRect(float(left), float(top), float(right), float(bottom));
}

// ----------------------------------------------------------------------------
// Drawing
// ----------------------------------------------------------------------------

static void android_view_GLES20Renderer_drawColor(JNIEnv* env, jobject canvas, jint renderer,
@@ -75,6 +115,14 @@ static JNINativeMethod gMethods[] = {
    {   "nSetViewport",       "(III)V",   (void*) android_view_GLES20Renderer_setViewport },
    {   "nPrepare",           "(I)V",     (void*) android_view_GLES20Renderer_prepare },

    {   "nSave",              "(II)I",    (void*) android_view_GLES20Renderer_save },
    {   "nRestore",           "(I)V",     (void*) android_view_GLES20Renderer_restore },
    {   "nRestoreToCount",    "(II)V",    (void*) android_view_GLES20Renderer_restoreToCount },
    {   "nGetSaveCount",      "(I)I",     (void*) android_view_GLES20Renderer_getSaveCount },

    {   "nClipRect",          "(IFFFF)Z", (void*) android_view_GLES20Renderer_clipRectF },
    {   "nClipRect",          "(IIIII)Z", (void*) android_view_GLES20Renderer_clipRect },

    {   "nDrawColor",         "(III)V",   (void*) android_view_GLES20Renderer_drawColor },
};

+6 −4
Original line number Diff line number Diff line
@@ -140,10 +140,12 @@ void Matrix4::loadOrtho(float left, float right, float bottom, float top, float
}

void Matrix4::dump() const {
	LOGD("Matrix4[");
	LOGD("  %f %f %f %f", mMat[0], mMat[4], mMat[ 8], mMat[12]);
	LOGD("  %f %f %f %f", mMat[1], mMat[5], mMat[ 9], mMat[13]);
	LOGD("  %f %f %f %f", mMat[2], mMat[6], mMat[10], mMat[14]);
	LOGD("  %f %f %f %f", mMat[3], mMat[7], mMat[11], mMat[15]);
	LOGD("]");
}

};
+70 −0
Original line number Diff line number Diff line
@@ -35,6 +35,9 @@ namespace android {

OpenGLRenderer::OpenGLRenderer() {
    LOGD("Create OpenGLRenderer");

    mSnapshot = new Snapshot;
    mSaveCount = 0;
}

OpenGLRenderer::~OpenGLRenderer() {
@@ -47,13 +50,80 @@ void OpenGLRenderer::setViewport(int width, int height) {
    mat4 ortho;
    ortho.loadOrtho(0, width, height, 0, 0, 1);
    ortho.copyTo(mOrthoMatrix);

    mWidth = width;
    mHeight = height;
}

void OpenGLRenderer::prepare() {
    glDisable(GL_SCISSOR_TEST);

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    glEnable(GL_SCISSOR_TEST);
    mSnapshot->clipRect.set(0.0f, 0.0f, mWidth, mHeight);
}

int OpenGLRenderer::getSaveCount() const {
	return mSaveCount;
}

int OpenGLRenderer::save(int flags) {
	return saveSnapshot();
}

void OpenGLRenderer::restore() {
	if (mSaveCount == 0) return;

	if (restoreSnapshot()) {
		setScissorFromClip();
	}
}

void OpenGLRenderer::restoreToCount(int saveCount) {
	if (saveCount <= 0 || saveCount > mSaveCount) return;

	bool restoreClip = false;

	while (mSaveCount != saveCount - 1) {
		restoreClip |= restoreSnapshot();
	}

	if (restoreClip) {
		setScissorFromClip();
	}
}

int OpenGLRenderer::saveSnapshot() {
	mSnapshot = new Snapshot(mSnapshot);
	mSaveCount++;
	return mSaveCount;
}

bool OpenGLRenderer::restoreSnapshot() {
	// TODO: handle local transformations
	bool restoreClip = mSnapshot->flags & Snapshot::kFlagClipSet;

	mSaveCount--;
	mSnapshot = mSnapshot->previous;

	return restoreClip;
}

void OpenGLRenderer::setScissorFromClip() {
	Rect clip = mSnapshot->clipRect;
	glScissor(clip.left, clip.top, clip.getWidth(), clip.getHeight());
}

bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom) {
	// TODO: take local translate transform into account
	bool clipped = mSnapshot->clipRect.intersect(left, top, right, bottom);
	if (clipped) {
		mSnapshot->flags |= Snapshot::kFlagClipSet;
		setScissorFromClip();
	}
	return clipped;
}

void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
+45 −1
Original line number Diff line number Diff line
@@ -19,8 +19,32 @@

#include <SkXfermode.h>

#include <utils/RefBase.h>

#include "Rect.h"

namespace android {

class Snapshot: public LightRefBase<Snapshot> {
public:
	Snapshot() { }

	Snapshot(const sp<Snapshot> s): clipRect(s->clipRect), flags(0), previous(s) { }

	enum Flags {
		kFlagClipSet = 0x1,
	};

	// Clipping rectangle at the time of this snapshot
	Rect clipRect;

	// Dirty flags
	int flags;

	// Previous snapshot in the frames stack
	sp<Snapshot> previous;
}; // struct Snapshot

class OpenGLRenderer {
public:
    OpenGLRenderer();
@@ -29,12 +53,32 @@ public:
    void setViewport(int width, int height);
    void prepare();

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

    bool clipRect(float left, float top, float right, float bottom);

    void drawColor(int color, SkXfermode::Mode mode);

private:
    int saveSnapshot();
    bool restoreSnapshot();

    void setScissorFromClip();

    // Dimensions of the drawing surface
    int mWidth, mHeight;

    // Matrix used for ortho projection in shaders
    float mOrthoMatrix[16];
};

    // Number of saved states
    int mSaveCount;
    // Current state
    sp<Snapshot> mSnapshot;
}; // class OpenGLRenderer

}; // namespace android

Loading