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

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

Merge "Add colored rectangles implementation in OpenGLRenderer."

parents 06f36212 9d5316e3
Loading
Loading
Loading
Loading
+3 −2
Original line number Original line Diff line number Diff line
@@ -186,10 +186,11 @@ class GLES20Canvas extends Canvas {


    @Override
    @Override
    public boolean getClipBounds(Rect bounds) {
    public boolean getClipBounds(Rect bounds) {
        // TODO: Implement
        return nGetClipBounds(mRenderer, bounds);
        return false;
    }
    }


    private native boolean nGetClipBounds(int renderer, Rect bounds);

    @Override
    @Override
    public boolean quickReject(float left, float top, float right, float bottom, EdgeType type) {
    public boolean quickReject(float left, float top, float right, float bottom, EdgeType type) {
        // TODO: Implement
        // TODO: Implement
+39 −0
Original line number Original line Diff line number Diff line
@@ -22,9 +22,22 @@
#include <SkXfermode.h>
#include <SkXfermode.h>


#include <OpenGLRenderer.h>
#include <OpenGLRenderer.h>
#include <Rect.h>
#include <ui/Rect.h>


namespace android {
namespace android {


using namespace uirenderer;

// ----------------------------------------------------------------------------
// Java APIs
// ----------------------------------------------------------------------------

static struct {
	jclass clazz;
	jmethodID set;
} gRectClassInfo;

// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Constructors
// Constructors
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
@@ -90,6 +103,17 @@ static bool android_view_GLES20Renderer_clipRect(JNIEnv* env, jobject canvas,
    return renderer->clipRect(float(left), float(top), float(right), float(bottom));
    return renderer->clipRect(float(left), float(top), float(right), float(bottom));
}
}


static bool android_view_GLES20Renderer_getClipBounds(JNIEnv* env, jobject canvas,
        OpenGLRenderer* renderer, jobject rect) {

	const android::uirenderer::Rect& bounds(renderer->getClipBounds());

	env->CallVoidMethod(rect, gRectClassInfo.set,
			int(bounds.left), int(bounds.top), int(bounds.right), int(bounds.bottom));

	return !bounds.isEmpty();
}

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


    {   "nGetClipBounds",     "(ILandroid/graphics/Rect;)Z",
    		(void*) android_view_GLES20Renderer_getClipBounds },

    {   "nTranslate",         "(IFF)V",   (void*) android_view_GLES20Renderer_translate },
    {   "nTranslate",         "(IFF)V",   (void*) android_view_GLES20Renderer_translate },
    {   "nRotate",            "(IF)V",    (void*) android_view_GLES20Renderer_rotate },
    {   "nRotate",            "(IF)V",    (void*) android_view_GLES20Renderer_rotate },
    {   "nScale",             "(IFF)V",   (void*) android_view_GLES20Renderer_scale },
    {   "nScale",             "(IFF)V",   (void*) android_view_GLES20Renderer_scale },
@@ -164,7 +191,19 @@ static JNINativeMethod gMethods[] = {
    {   "nDrawColor",         "(III)V",   (void*) android_view_GLES20Renderer_drawColor },
    {   "nDrawColor",         "(III)V",   (void*) android_view_GLES20Renderer_drawColor },
};
};


#define FIND_CLASS(var, className) \
        var = env->FindClass(className); \
        LOG_FATAL_IF(! var, "Unable to find class " className); \
        var = jclass(env->NewGlobalRef(var));

#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
        var = env->GetMethodID(clazz, methodName, methodDescriptor); \
        LOG_FATAL_IF(! var, "Unable to find method " methodName);

int register_android_view_GLES20Canvas(JNIEnv* env) {
int register_android_view_GLES20Canvas(JNIEnv* env) {
	FIND_CLASS(gRectClassInfo.clazz, "android/graphics/Rect");
	GET_METHOD_ID(gRectClassInfo.set, gRectClassInfo.clazz, "set", "(IIII)V");

    return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
    return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
}
}


+19 −2
Original line number Original line Diff line number Diff line
@@ -14,7 +14,7 @@
 * limitations under the License.
 * limitations under the License.
 */
 */


#define LOG_TAG "UIMatrix"
#define LOG_TAG "Matrix"


#include <math.h>
#include <math.h>
#include <stdlib.h>
#include <stdlib.h>
@@ -27,6 +27,7 @@
#include "Matrix.h"
#include "Matrix.h"


namespace android {
namespace android {
namespace uirenderer {


void Matrix4::loadIdentity() {
void Matrix4::loadIdentity() {
	mMat[0]  = 1.0f;
	mMat[0]  = 1.0f;
@@ -175,6 +176,21 @@ void Matrix4::loadOrtho(float left, float right, float bottom, float top, float
    mMat[14] = -(far + near) / (far - near);
    mMat[14] = -(far + near) / (far - near);
}
}


#define MUL_ADD_STORE(a, b, c) a = (a) * (b) + (c)

void Matrix4::mapRect(Rect& r) const {
	const float sx = mMat[0];
	const float sy = mMat[5];

	const float tx = mMat[12];
	const float ty = mMat[13];

	MUL_ADD_STORE(r.left, sx, tx);
	MUL_ADD_STORE(r.right, sx, tx);
	MUL_ADD_STORE(r.top, sy, ty);
	MUL_ADD_STORE(r.bottom, sy, ty);
}

void Matrix4::dump() const {
void Matrix4::dump() const {
	LOGD("Matrix4[");
	LOGD("Matrix4[");
	LOGD("  %f %f %f %f", mMat[0], mMat[4], mMat[ 8], mMat[12]);
	LOGD("  %f %f %f %f", mMat[0], mMat[4], mMat[ 8], mMat[12]);
@@ -184,4 +200,5 @@ void Matrix4::dump() const {
	LOGD("]");
	LOGD("]");
}
}


};
}; // namespace uirenderer
}; // namespace android
+9 −3
Original line number Original line Diff line number Diff line
@@ -14,12 +14,15 @@
 * limitations under the License.
 * limitations under the License.
 */
 */


#ifndef ANDROID_MATRIX_H
#ifndef ANDROID_UI_MATRIX_H
#define ANDROID_MATRIX_H
#define ANDROID_UI_MATRIX_H


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


#include "Rect.h"

namespace android {
namespace android {
namespace uirenderer {


///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Classes
// Classes
@@ -83,6 +86,8 @@ public:
	void copyTo(float* v) const;
	void copyTo(float* v) const;
	void copyTo(SkMatrix& v) const;
	void copyTo(SkMatrix& v) const;


	void mapRect(Rect& r) const;

	void dump() const;
	void dump() const;


private:
private:
@@ -103,6 +108,7 @@ private:


typedef Matrix4 mat4;
typedef Matrix4 mat4;


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


#endif // ANDROID_MATRIX_H
#endif // ANDROID_UI_MATRIX_H
+172 −5
Original line number Original line Diff line number Diff line
@@ -21,6 +21,7 @@
#include <sys/types.h>
#include <sys/types.h>


#include <utils/Errors.h>
#include <utils/Errors.h>
#include <utils/KeyedVector.h>
#include <utils/Log.h>
#include <utils/Log.h>


#include <GLES2/gl2.h>
#include <GLES2/gl2.h>
@@ -32,6 +33,129 @@
#include "Matrix.h"
#include "Matrix.h"


namespace android {
namespace android {
namespace uirenderer {

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

#define SOLID_WHITE { 1.0f, 1.0f, 1.0f, 1.0f }

#define P(x, y) { x, y }

///////////////////////////////////////////////////////////////////////////////
// Globals
///////////////////////////////////////////////////////////////////////////////

const Vertex gDrawColorVertices[] = {
		{ P(0.0f, 0.0f), SOLID_WHITE },
		{ P(1.0f, 0.0f), SOLID_WHITE },
		{ P(0.0f, 1.0f), SOLID_WHITE },
		{ P(1.0f, 1.0f), SOLID_WHITE }
};

///////////////////////////////////////////////////////////////////////////////
// Shaders
///////////////////////////////////////////////////////////////////////////////

#define SHADER_SOURCE(name, source) const char* name = #source

#include "shaders/drawColor.vert"
#include "shaders/drawColor.frag"

Program::Program(const char* vertex, const char* fragment) {
	vertexShader = buildShader(vertex, GL_VERTEX_SHADER);
	fragmentShader = buildShader(fragment, GL_FRAGMENT_SHADER);

	id = glCreateProgram();
	glAttachShader(id, vertexShader);
	glAttachShader(id, fragmentShader);
	glLinkProgram(id);

	GLint status;
	glGetProgramiv(id, GL_LINK_STATUS, &status);
	if (status != GL_TRUE) {
		GLint infoLen = 0;
		glGetProgramiv(id, GL_INFO_LOG_LENGTH, &infoLen);
		if (infoLen > 1) {
			char* log = (char*) malloc(sizeof(char) * infoLen);
			glGetProgramInfoLog(id, infoLen, 0, log);
			LOGE("Error while linking shaders: %s", log);
			delete log;
		}
		glDeleteProgram(id);
	}
}

Program::~Program() {
	glDeleteShader(vertexShader);
	glDeleteShader(fragmentShader);
	glDeleteProgram(id);
}

void Program::use() {
	glUseProgram(id);
}

int Program::addAttrib(const char* name) {
	int slot = glGetAttribLocation(id, name);
	attributes.add(name, slot);
	return slot;
}

int Program::getAttrib(const char* name) {
	return attributes.valueFor(name);
}

int Program::addUniform(const char* name) {
	int slot = glGetUniformLocation(id, name);
	uniforms.add(name, slot);
	return slot;
}

int Program::getUniform(const char* name) {
	return uniforms.valueFor(name);
}

GLuint Program::buildShader(const char* source, GLenum type) {
	GLuint shader = glCreateShader(type);
	glShaderSource(shader, 1, &source, 0);
	glCompileShader(shader);

	GLint status;
	glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
	if (status != GL_TRUE) {
		// Some drivers return wrong values for GL_INFO_LOG_LENGTH
		// use a fixed size instead
		GLchar log[512];
		glGetShaderInfoLog(shader, sizeof(log), 0, &log[0]);
		LOGE("Error while compiling shader: %s", log);
		glDeleteShader(shader);
	}

	return shader;
}

DrawColorProgram::DrawColorProgram():
		Program(gDrawColorVertexShader, gDrawColorFragmentShader) {
	position = addAttrib("position");
	color = addAttrib("color");
	projection = addUniform("projection");
	modelView = addUniform("modelView");
}

///////////////////////////////////////////////////////////////////////////////
// Support
///////////////////////////////////////////////////////////////////////////////

const Rect& Snapshot::getMappedClip() {
	if (flags & kFlagDirtyTransform) {
		flags &= ~kFlagDirtyTransform;
		mappedClip.set(clipRect);
		transform.mapRect(mappedClip);
	}
	return mappedClip;
}


///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Constructors/destructor
// Constructors/destructor
@@ -39,6 +163,8 @@ namespace android {


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

    mDrawColorShader = new DrawColorProgram;
}
}


OpenGLRenderer::~OpenGLRenderer() {
OpenGLRenderer::~OpenGLRenderer() {
@@ -114,7 +240,6 @@ int OpenGLRenderer::saveSnapshot() {
}
}


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


	mSaveCount--;
	mSaveCount--;
@@ -132,18 +257,22 @@ bool OpenGLRenderer::restoreSnapshot() {


void OpenGLRenderer::translate(float dx, float dy) {
void OpenGLRenderer::translate(float dx, float dy) {
	mSnapshot->transform.translate(dx, dy, 0.0f);
	mSnapshot->transform.translate(dx, dy, 0.0f);
	mSnapshot->flags |= Snapshot::kFlagDirtyTransform;
}
}


void OpenGLRenderer::rotate(float degrees) {
void OpenGLRenderer::rotate(float degrees) {
	mSnapshot->transform.rotate(degrees, 0.0f, 0.0f, 1.0f);
	mSnapshot->transform.rotate(degrees, 0.0f, 0.0f, 1.0f);
	mSnapshot->flags |= Snapshot::kFlagDirtyTransform;
}
}


void OpenGLRenderer::scale(float sx, float sy) {
void OpenGLRenderer::scale(float sx, float sy) {
	mSnapshot->transform.scale(sx, sy, 1.0f);
	mSnapshot->transform.scale(sx, sy, 1.0f);
	mSnapshot->flags |= Snapshot::kFlagDirtyTransform;
}
}


void OpenGLRenderer::setMatrix(SkMatrix* matrix) {
void OpenGLRenderer::setMatrix(SkMatrix* matrix) {
	mSnapshot->transform.load(*matrix);
	mSnapshot->transform.load(*matrix);
	mSnapshot->flags |= Snapshot::kFlagDirtyTransform;
}
}


void OpenGLRenderer::getMatrix(SkMatrix* matrix) {
void OpenGLRenderer::getMatrix(SkMatrix* matrix) {
@@ -153,6 +282,7 @@ void OpenGLRenderer::getMatrix(SkMatrix* matrix) {
void OpenGLRenderer::concatMatrix(SkMatrix* matrix) {
void OpenGLRenderer::concatMatrix(SkMatrix* matrix) {
	mat4 m(*matrix);
	mat4 m(*matrix);
	mSnapshot->transform.multiply(m);
	mSnapshot->transform.multiply(m);
	mSnapshot->flags |= Snapshot::kFlagDirtyTransform;
}
}


///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
@@ -160,12 +290,15 @@ void OpenGLRenderer::concatMatrix(SkMatrix* matrix) {
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////


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

const Rect& OpenGLRenderer::getClipBounds() {
	return mSnapshot->clipRect;
}
}


bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom) {
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);
	bool clipped = mSnapshot->clipRect.intersect(left, top, right, bottom);
	if (clipped) {
	if (clipped) {
		mSnapshot->flags |= Snapshot::kFlagClipSet;
		mSnapshot->flags |= Snapshot::kFlagClipSet;
@@ -179,7 +312,41 @@ bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom)
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////


void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
	LOGD("Drawing color");
	GLfloat a = ((color >> 24) & 0xFF) / 255.0f;
	GLfloat r = ((color >> 16) & 0xFF) / 255.0f;
	GLfloat g = ((color >>  8) & 0xFF) / 255.0f;
	GLfloat b = ((color      ) & 0xFF) / 255.0f;

	// TODO Optimize this section
	const Rect& clip = mSnapshot->getMappedClip();

	mat4 modelView;
	modelView.loadScale(clip.getWidth(), clip.getHeight(), 1.0f);
	modelView.translate(clip.left, clip.top, 0.0f);

	float matrix[16];
	modelView.copyTo(matrix);
	// TODO Optimize this section

	mDrawColorShader->use();

	glUniformMatrix4fv(mDrawColorShader->projection, 1, GL_FALSE, &mOrthoMatrix[0]);
	glUniformMatrix4fv(mDrawColorShader->modelView, 1, GL_FALSE, &matrix[0]);

	glEnableVertexAttribArray(mDrawColorShader->position);

	GLsizei stride = sizeof(Vertex);
	const GLvoid* p = &gDrawColorVertices[0].position[0];

	glVertexAttribPointer(mDrawColorShader->position, 2, GL_FLOAT, GL_FALSE, stride, p);
	glVertexAttrib4f(mDrawColorShader->color, r, g, b, a);

	GLsizei vertexCount = sizeof(gDrawColorVertices) / sizeof(Vertex);
	glDrawArrays(GL_TRIANGLE_STRIP, 0, vertexCount);

	glDisableVertexAttribArray(mDrawColorShader->position);
	glDisableVertexAttribArray(mDrawColorShader->color);
}
}


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