Home | History | Annotate | Download | only in jni
      1 /*
      2  * Copyright 2013 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "gles3jni.h"
     18 #include <EGL/egl.h>
     19 
     20 #define STR(s) #s
     21 #define STRV(s) STR(s)
     22 
     23 #define POS_ATTRIB 0
     24 #define COLOR_ATTRIB 1
     25 #define SCALEROT_ATTRIB 2
     26 #define OFFSET_ATTRIB 3
     27 
     28 static const char VERTEX_SHADER[] =
     29     "#version 300 es\n"
     30     "layout(location = " STRV(POS_ATTRIB) ") in vec2 pos;\n"
     31     "layout(location=" STRV(COLOR_ATTRIB) ") in vec4 color;\n"
     32     "layout(location=" STRV(SCALEROT_ATTRIB) ") in vec4 scaleRot;\n"
     33     "layout(location=" STRV(OFFSET_ATTRIB) ") in vec2 offset;\n"
     34     "out vec4 vColor;\n"
     35     "void main() {\n"
     36     "    mat2 sr = mat2(scaleRot.xy, scaleRot.zw);\n"
     37     "    gl_Position = vec4(sr*pos + offset, 0.0, 1.0);\n"
     38     "    vColor = color;\n"
     39     "}\n";
     40 
     41 static const char FRAGMENT_SHADER[] =
     42     "#version 300 es\n"
     43     "precision mediump float;\n"
     44     "in vec4 vColor;\n"
     45     "out vec4 outColor;\n"
     46     "void main() {\n"
     47     "    outColor = vColor;\n"
     48     "}\n";
     49 
     50 class RendererES3: public Renderer {
     51 public:
     52     RendererES3();
     53     virtual ~RendererES3();
     54     bool init();
     55 
     56 private:
     57     enum {VB_INSTANCE, VB_SCALEROT, VB_OFFSET, VB_COUNT};
     58 
     59     virtual float* mapOffsetBuf();
     60     virtual void unmapOffsetBuf();
     61     virtual float* mapTransformBuf();
     62     virtual void unmapTransformBuf();
     63     virtual void draw(unsigned int numInstances);
     64 
     65     const EGLContext mEglContext;
     66     GLuint mProgram;
     67     GLuint mVB[VB_COUNT];
     68     GLuint mVBState;
     69 };
     70 
     71 Renderer* createES3Renderer() {
     72     RendererES3* renderer = new RendererES3;
     73     if (!renderer->init()) {
     74         delete renderer;
     75         return NULL;
     76     }
     77     return renderer;
     78 }
     79 
     80 RendererES3::RendererES3()
     81 :   mEglContext(eglGetCurrentContext()),
     82     mProgram(0),
     83     mVBState(0)
     84 {
     85     for (int i = 0; i < VB_COUNT; i++)
     86         mVB[i] = 0;
     87 }
     88 
     89 bool RendererES3::init() {
     90     mProgram = createProgram(VERTEX_SHADER, FRAGMENT_SHADER);
     91     if (!mProgram)
     92         return false;
     93 
     94     glGenBuffers(VB_COUNT, mVB);
     95     glBindBuffer(GL_ARRAY_BUFFER, mVB[VB_INSTANCE]);
     96     glBufferData(GL_ARRAY_BUFFER, sizeof(QUAD), &QUAD[0], GL_STATIC_DRAW);
     97     glBindBuffer(GL_ARRAY_BUFFER, mVB[VB_SCALEROT]);
     98     glBufferData(GL_ARRAY_BUFFER, MAX_INSTANCES * 4*sizeof(float), NULL, GL_DYNAMIC_DRAW);
     99     glBindBuffer(GL_ARRAY_BUFFER, mVB[VB_OFFSET]);
    100     glBufferData(GL_ARRAY_BUFFER, MAX_INSTANCES * 2*sizeof(float), NULL, GL_STATIC_DRAW);
    101 
    102     glGenVertexArrays(1, &mVBState);
    103     glBindVertexArray(mVBState);
    104 
    105     glBindBuffer(GL_ARRAY_BUFFER, mVB[VB_INSTANCE]);
    106     glVertexAttribPointer(POS_ATTRIB, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)offsetof(Vertex, pos));
    107     glVertexAttribPointer(COLOR_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), (const GLvoid*)offsetof(Vertex, rgba));
    108     glEnableVertexAttribArray(POS_ATTRIB);
    109     glEnableVertexAttribArray(COLOR_ATTRIB);
    110 
    111     glBindBuffer(GL_ARRAY_BUFFER, mVB[VB_SCALEROT]);
    112     glVertexAttribPointer(SCALEROT_ATTRIB, 4, GL_FLOAT, GL_FALSE, 4*sizeof(float), 0);
    113     glEnableVertexAttribArray(SCALEROT_ATTRIB);
    114     glVertexAttribDivisor(SCALEROT_ATTRIB, 1);
    115 
    116     glBindBuffer(GL_ARRAY_BUFFER, mVB[VB_OFFSET]);
    117     glVertexAttribPointer(OFFSET_ATTRIB, 2, GL_FLOAT, GL_FALSE, 2*sizeof(float), 0);
    118     glEnableVertexAttribArray(OFFSET_ATTRIB);
    119     glVertexAttribDivisor(OFFSET_ATTRIB, 1);
    120 
    121     ALOGV("Using OpenGL ES 3.0 renderer");
    122     return true;
    123 }
    124 
    125 RendererES3::~RendererES3() {
    126     /* The destructor may be called after the context has already been
    127      * destroyed, in which case our objects have already been destroyed.
    128      *
    129      * If the context exists, it must be current. This only happens when we're
    130      * cleaning up after a failed init().
    131      */
    132     if (eglGetCurrentContext() != mEglContext)
    133         return;
    134     glDeleteVertexArrays(1, &mVBState);
    135     glDeleteBuffers(VB_COUNT, mVB);
    136     glDeleteProgram(mProgram);
    137 }
    138 
    139 float* RendererES3::mapOffsetBuf() {
    140     glBindBuffer(GL_ARRAY_BUFFER, mVB[VB_OFFSET]);
    141     return (float*)glMapBufferRange(GL_ARRAY_BUFFER,
    142             0, MAX_INSTANCES * 2*sizeof(float),
    143             GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
    144 }
    145 
    146 void RendererES3::unmapOffsetBuf() {
    147     glUnmapBuffer(GL_ARRAY_BUFFER);
    148 }
    149 
    150 float* RendererES3::mapTransformBuf() {
    151     glBindBuffer(GL_ARRAY_BUFFER, mVB[VB_SCALEROT]);
    152     return (float*)glMapBufferRange(GL_ARRAY_BUFFER,
    153             0, MAX_INSTANCES * 4*sizeof(float),
    154             GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
    155 }
    156 
    157 void RendererES3::unmapTransformBuf() {
    158     glUnmapBuffer(GL_ARRAY_BUFFER);
    159 }
    160 
    161 void RendererES3::draw(unsigned int numInstances) {
    162     glUseProgram(mProgram);
    163     glBindVertexArray(mVBState);
    164     glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, numInstances);
    165 }
    166