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

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

Add support for transformations.

This change adds partial support for the following transforms:
- scale()
- translate()
- rotate()
- setMatrix()
- getMatrix()

The transform is stored in a snapshot and saved/restored as needed.
The transform is currently not applied to the clip rect and is not
mapped to the vertex shader.

Change-Id: Id48993453311200804149917d0c126a4d0471226
parent bb9524b6
Loading
Loading
Loading
Loading
+19 −8
Original line number Diff line number Diff line
@@ -212,9 +212,11 @@ class GLES20Canvas extends Canvas {

    @Override
    public void translate(float dx, float dy) {
        // TODO: Implement
        nTranslate(mRenderer, dx, dy);
    }
    
    private native void nTranslate(int renderer, float dx, float dy);

    @Override
    public void skew(float sx, float sy) {
        throw new UnsupportedOperationException();
@@ -222,30 +224,39 @@ class GLES20Canvas extends Canvas {

    @Override
    public void rotate(float degrees) {
        // TODO: Implement
        nRotate(mRenderer, degrees);
    }
    
    private native void nRotate(int renderer, float degrees);

    @Override
    public void scale(float sx, float sy) {
        // TODO: Implement
        nScale(mRenderer, sx, sy);
    }
    
    private native void nScale(int renderer, float sx, float sy);

    @Override
    public void setMatrix(Matrix matrix) {
        // TODO: Implement
        nSetMatrix(mRenderer, matrix.native_instance);
    }
    
    private native void nSetMatrix(int renderer, int matrix);

    @Override
    public void getMatrix(Matrix ctm) {
        // TODO: Implement
    public void getMatrix(Matrix matrix) {
        nGetMatrix(mRenderer, matrix.native_instance);
    }
    
    private native void nGetMatrix(int renderer, int matrix);

    @Override
    public void concat(Matrix matrix) {
        // TODO: Implement
        nConcatMatrix(mRenderer, matrix.native_instance);
    }
    
    private native void nConcatMatrix(int renderer, int matrix);
    
    ///////////////////////////////////////////////////////////////////////////
    // State management
    ///////////////////////////////////////////////////////////////////////////
+69 −31
Original line number Diff line number Diff line
@@ -18,12 +18,11 @@
#include <nativehelper/JNIHelp.h>
#include <android_runtime/AndroidRuntime.h>

#include <SkMatrix.h>
#include <SkXfermode.h>

#include <OpenGLRenderer.h>

#define UI ((OpenGLRenderer*) renderer)

namespace android {

// ----------------------------------------------------------------------------
@@ -34,73 +33,104 @@ static OpenGLRenderer* android_view_GLES20Renderer_createRenderer(JNIEnv* env, j
    return new OpenGLRenderer;
}

static void android_view_GLES20Renderer_destroyRenderer(JNIEnv* env, jobject canvas, jint renderer) {
    delete UI;
static void android_view_GLES20Renderer_destroyRenderer(JNIEnv* env, jobject canvas,
        OpenGLRenderer* renderer) {
    delete renderer;
}

// ----------------------------------------------------------------------------
// Setup
// ----------------------------------------------------------------------------

static void android_view_GLES20Renderer_setViewport(JNIEnv* env, jobject canvas, jint renderer,
        jint width, jint height) {

    UI->setViewport(width, height);
static void android_view_GLES20Renderer_setViewport(JNIEnv* env, jobject canvas,
        OpenGLRenderer* renderer, jint width, jint height) {
    renderer->setViewport(width, height);
}

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

    UI->prepare();
static void android_view_GLES20Renderer_prepare(JNIEnv* env, jobject canvas,
        OpenGLRenderer* renderer) {
    renderer->prepare();
}

// ----------------------------------------------------------------------------
// State
// ----------------------------------------------------------------------------

static jint android_view_GLES20Renderer_save(JNIEnv* env, jobject canvas, jint renderer,
static jint android_view_GLES20Renderer_save(JNIEnv* env, jobject canvas, OpenGLRenderer* renderer,
        jint flags) {
    return renderer->save(flags);
}

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

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,
        OpenGLRenderer* renderer) {
    renderer->restore();
}

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

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

static bool android_view_GLES20Renderer_clipRectF(JNIEnv* env, jobject canvas,
        OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom) {
    return renderer->clipRect(left, top, right, bottom);
}

    UI->restoreToCount(saveCount);
static bool android_view_GLES20Renderer_clipRect(JNIEnv* env, jobject canvas,
        OpenGLRenderer* renderer, jint left, jint top, jint right, jint bottom) {
    return renderer->clipRect(float(left), float(top), float(right), float(bottom));
}

// ----------------------------------------------------------------------------
// Clipping
// Transforms
// ----------------------------------------------------------------------------

static bool android_view_GLES20Renderer_clipRectF(JNIEnv* env, jobject canvas, jint renderer,
        jfloat left, jfloat top, jfloat right, jfloat bottom) {
static void android_view_GLES20Renderer_translate(JNIEnv* env, jobject canvas,
        OpenGLRenderer* renderer, jfloat dx, jfloat dy) {
	renderer->translate(dx, dy);
}

    return UI->clipRect(left, top, right, bottom);
static void android_view_GLES20Renderer_rotate(JNIEnv* env, jobject canvas,
        OpenGLRenderer* renderer, jfloat degrees) {
	renderer->rotate(degrees);
}

static bool android_view_GLES20Renderer_clipRect(JNIEnv* env, jobject canvas, jint renderer,
        jint left, jint top, jint right, jint bottom) {
static void android_view_GLES20Renderer_scale(JNIEnv* env, jobject canvas,
        OpenGLRenderer* renderer, jfloat sx, jfloat sy) {
	renderer->scale(sx, sy);
}

    return UI->clipRect(float(left), float(top), float(right), float(bottom));
static void android_view_GLES20Renderer_setMatrix(JNIEnv* env, jobject canvas,
        OpenGLRenderer* renderer, SkMatrix* matrix) {
	renderer->setMatrix(matrix);
}

static void android_view_GLES20Renderer_getMatrix(JNIEnv* env, jobject canvas,
        OpenGLRenderer* renderer, SkMatrix* matrix) {
	renderer->getMatrix(matrix);
}

static void android_view_GLES20Renderer_concatMatrix(JNIEnv* env, jobject canvas,
        OpenGLRenderer* renderer, SkMatrix* matrix) {
	renderer->concatMatrix(matrix);
}

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

static void android_view_GLES20Renderer_drawColor(JNIEnv* env, jobject canvas, jint renderer,
        jint color, jint mode) {

    UI->drawColor(color, (SkXfermode::Mode) mode);
static void android_view_GLES20Renderer_drawColor(JNIEnv* env, jobject canvas,
        OpenGLRenderer* renderer, jint color, jint mode) {
    renderer->drawColor(color, (SkXfermode::Mode) mode);
}

// ----------------------------------------------------------------------------
@@ -123,6 +153,14 @@ static JNINativeMethod gMethods[] = {
    {   "nClipRect",          "(IFFFF)Z", (void*) android_view_GLES20Renderer_clipRectF },
    {   "nClipRect",          "(IIIII)Z", (void*) android_view_GLES20Renderer_clipRect },

    {   "nTranslate",         "(IFF)V",   (void*) android_view_GLES20Renderer_translate },
    {   "nRotate",            "(IF)V",    (void*) android_view_GLES20Renderer_rotate },
    {   "nScale",             "(IFF)V",   (void*) android_view_GLES20Renderer_scale },

    {   "nSetMatrix",         "(II)V",    (void*) android_view_GLES20Renderer_setMatrix },
    {   "nGetMatrix",         "(II)V",    (void*) android_view_GLES20Renderer_getMatrix },
    {   "nConcatMatrix",      "(II)V",    (void*) android_view_GLES20Renderer_concatMatrix },

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

+4 −1
Original line number Diff line number Diff line
@@ -37,7 +37,10 @@ public class Matrix {
    public static final int MPERSP_1 = 7;   //!< use with getValues/setValues
    public static final int MPERSP_2 = 8;   //!< use with getValues/setValues

    /* package */ int native_instance;
    /**
     * @hide
     */
    public int native_instance;

    /**
     * Create an identity matrix
+65 −29
Original line number Diff line number Diff line
@@ -22,30 +22,32 @@

#include <utils/Log.h>

#include <SkMatrix.h>

#include "Matrix.h"

namespace android {

void Matrix4::loadIdentity() {
	mMat[0]  = 1;
	mMat[1]  = 0;
	mMat[2]  = 0;
	mMat[3]  = 0;

	mMat[4]  = 0;
	mMat[5]  = 1;
	mMat[6]  = 0;
	mMat[7]  = 0;

	mMat[8]  = 0;
	mMat[9]  = 0;
	mMat[10] = 1;
	mMat[11] = 0;

	mMat[12] = 0;
	mMat[13] = 0;
	mMat[14] = 0;
	mMat[15] = 1;
	mMat[0]  = 1.0f;
	mMat[1]  = 0.0f;
	mMat[2]  = 0.0f;
	mMat[3]  = 0.0f;

	mMat[4]  = 0.0f;
	mMat[5]  = 1.0f;
	mMat[6]  = 0.0f;
	mMat[7]  = 0.0f;

	mMat[8]  = 0.0f;
	mMat[9]  = 0.0f;
	mMat[10] = 1.0f;
	mMat[11] = 0.0f;

	mMat[12] = 0.0f;
	mMat[13] = 0.0f;
	mMat[14] = 0.0f;
	mMat[15] = 1.0f;
}

void Matrix4::load(const float* v) {
@@ -56,6 +58,40 @@ void Matrix4::load(const Matrix4& v) {
	memcpy(mMat, v.mMat, sizeof(mMat));
}

void Matrix4::load(const SkMatrix& v) {
	memset(mMat, 0, sizeof(mMat));

	mMat[0]  = v[SkMatrix::kMScaleX];
	mMat[4]  = v[SkMatrix::kMSkewX];
	mMat[12] = v[SkMatrix::kMTransX];

	mMat[1]  = v[SkMatrix::kMSkewY];
	mMat[5]  = v[SkMatrix::kMScaleY];
	mMat[13] = v[SkMatrix::kMTransY];

	mMat[3]  = v[SkMatrix::kMPersp0];
	mMat[7]  = v[SkMatrix::kMPersp1];
	mMat[15] = v[SkMatrix::kMPersp2];

	mMat[10] = 1.0f;
}

void Matrix4::copyTo(SkMatrix& v) const {
	v.reset();

	v.set(SkMatrix::kMScaleX, mMat[0]);
	v.set(SkMatrix::kMSkewX,  mMat[4]);
	v.set(SkMatrix::kMTransX, mMat[12]);

	v.set(SkMatrix::kMSkewY,  mMat[1]);
	v.set(SkMatrix::kMScaleY, mMat[5]);
	v.set(SkMatrix::kMTransY, mMat[13]);

	v.set(SkMatrix::kMPersp0, mMat[3]);
	v.set(SkMatrix::kMPersp1, mMat[7]);
	v.set(SkMatrix::kMPersp2, mMat[15]);
}

void Matrix4::copyTo(float* v) const {
	memcpy(v, mMat, sizeof(mMat));
}
@@ -75,13 +111,13 @@ void Matrix4::loadScale(float sx, float sy, float sz) {
}

void Matrix4::loadRotate(float angle, float x, float y, float z) {
	mMat[3]  = 0;
	mMat[7]  = 0;
	mMat[11] = 0;
	mMat[12] = 0;
	mMat[13] = 0;
	mMat[14] = 0;
	mMat[15] = 1;
	mMat[3]  = 0.0f;
	mMat[7]  = 0.0f;
	mMat[11] = 0.0f;
	mMat[12] = 0.0f;
	mMat[13] = 0.0f;
	mMat[14] = 0.0f;
	mMat[15] = 1.0f;

	angle *= float(M_PI / 180.0f);
	float c = cosf(angle);
@@ -131,9 +167,9 @@ void Matrix4::loadMultiply(const Matrix4& u, const Matrix4& v) {

void Matrix4::loadOrtho(float left, float right, float bottom, float top, float near, float far) {
    loadIdentity();
    mMat[0]  = 2 / (right - left);
    mMat[5]  = 2 / (top - bottom);
    mMat[10] = -2 / (far - near);
    mMat[0]  = 2.0f / (right - left);
    mMat[5]  = 2.0f / (top - bottom);
    mMat[10] = -2.0f / (far - near);
    mMat[12] = -(right + left) / (right - left);
    mMat[13] = -(top + bottom) / (top - bottom);
    mMat[14] = -(far + near) / (far - near);
+9 −1
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@
#ifndef ANDROID_MATRIX_H
#define ANDROID_MATRIX_H

#include <SkMatrix.h>

namespace android {

///////////////////////////////////////////////////////////////////////////////
@@ -37,10 +39,15 @@ public:
		load(v);
	}

	Matrix4(const SkMatrix& v) {
		load(v);
	}

	void loadIdentity();

	void load(const float* v);
	void load(const Matrix4& v);
	void load(const SkMatrix& v);

	void loadTranslate(float x, float y, float z);
	void loadScale(float sx, float sy, float sz);
@@ -74,10 +81,11 @@ public:
	}

	void copyTo(float* v) const;
	void copyTo(SkMatrix& v) const;

	void dump() const;

//private:
private:
    inline float get(int i, int j) const {
        return mMat[i * 4 + j];
    }
Loading