X-Git-Url: https://gerrit.akraino.org/r/gitweb?a=blobdiff_plain;f=src%2Ftype3_AndroidCloud%2Fanbox-master%2Fsrc%2Fanbox%2Fgraphics%2Femugl%2FTextureDraw.cpp;fp=src%2Ftype3_AndroidCloud%2Fanbox-master%2Fsrc%2Fanbox%2Fgraphics%2Femugl%2FTextureDraw.cpp;h=8bb1e592f11687181314b0f3ffc9a14123384844;hb=e26c1ec581be598521517829adba8c8dd23a768f;hp=0000000000000000000000000000000000000000;hpb=6699c1aea74eeb0eb400e6299079f0c7576f716f;p=iec.git diff --git a/src/type3_AndroidCloud/anbox-master/src/anbox/graphics/emugl/TextureDraw.cpp b/src/type3_AndroidCloud/anbox-master/src/anbox/graphics/emugl/TextureDraw.cpp new file mode 100644 index 0000000..8bb1e59 --- /dev/null +++ b/src/type3_AndroidCloud/anbox-master/src/anbox/graphics/emugl/TextureDraw.cpp @@ -0,0 +1,229 @@ +// Copyright (C) 2015 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. + +#include "anbox/graphics/emugl/TextureDraw.h" +#include "anbox/graphics/emugl/DispatchTables.h" +#include "anbox/logger.h" + +#include +#include +#include + +#include + +// M_PI isn't defined in C++ (when strict ISO compliance is enabled) +#ifndef M_PI +#define M_PI 3.14159265358979323846264338327 +#endif + +namespace { + +// Helper function to create a new shader. +// |shaderType| is the shader type (e.g. GL_VERTEX_SHADER). +// |shaderText| is a 0-terminated C string for the shader source to use. +// On success, return the handle of the new compiled shader, or 0 on failure. +GLuint createShader(GLint shaderType, const char* shaderText) { + // Create new shader handle and attach source. + GLuint shader = s_gles2.glCreateShader(shaderType); + if (!shader) { + return 0; + } + const GLchar* text = static_cast(shaderText); + const GLint textLen = ::strlen(shaderText); + s_gles2.glShaderSource(shader, 1, &text, &textLen); + + // Compiler the shader. + GLint success; + s_gles2.glCompileShader(shader); + s_gles2.glGetShaderiv(shader, GL_COMPILE_STATUS, &success); + if (success == GL_FALSE) { + s_gles2.glDeleteShader(shader); + return 0; + } + + return shader; +} + +// No scaling / projection since we want to fill the whole viewport with +// the texture, hence a trivial vertex shader. +const char kVertexShaderSource[] = + "attribute vec4 position;\n" + "attribute vec2 inCoord;\n" + "varying lowp vec2 outCoord;\n" + "void main(void) {\n" + " gl_Position.x = position.x;\n" + " gl_Position.y = position.y;\n" + " gl_Position.zw = position.zw;\n" + " outCoord = inCoord;\n" + "}\n"; + +// Similarly, just interpolate texture coordinates. +const char kFragmentShaderSource[] = + "varying lowp vec2 outCoord;\n" + "uniform sampler2D texture;\n" + + "void main(void) {\n" + " gl_FragColor = texture2D(texture, outCoord);\n" + "}\n"; + +// Hard-coded arrays of vertex information. +struct Vertex { + float pos[3]; + float coord[2]; +}; + +const Vertex kVertices[] = { + {{+1, -1, +0}, {+1, +1}}, + {{+1, +1, +0}, {+1, +0}}, + {{-1, +1, +0}, {+0, +0}}, + {{-1, -1, +0}, {+0, +1}}, +}; + +const GLubyte kIndices[] = {0, 1, 2, 2, 3, 0}; +const GLint kIndicesLen = sizeof(kIndices) / sizeof(kIndices[0]); + +} // namespace + +TextureDraw::TextureDraw(EGLDisplay) + : mVertexShader(0), + mFragmentShader(0), + mProgram(0), + mPositionSlot(-1), + mInCoordSlot(-1), + mTextureSlot(-1) { + // Create shaders and program. + mVertexShader = createShader(GL_VERTEX_SHADER, kVertexShaderSource); + mFragmentShader = createShader(GL_FRAGMENT_SHADER, kFragmentShaderSource); + + mProgram = s_gles2.glCreateProgram(); + s_gles2.glAttachShader(mProgram, mVertexShader); + s_gles2.glAttachShader(mProgram, mFragmentShader); + + GLint success; + s_gles2.glLinkProgram(mProgram); + s_gles2.glGetProgramiv(mProgram, GL_LINK_STATUS, &success); + if (success == GL_FALSE) { + GLchar messages[256]; + s_gles2.glGetProgramInfoLog(mProgram, sizeof(messages), 0, &messages[0]); + ERROR("Could not create/link program: %s", messages); + s_gles2.glDeleteProgram(mProgram); + mProgram = 0; + return; + } + + s_gles2.glUseProgram(mProgram); + + // Retrieve attribute/uniform locations. + mPositionSlot = s_gles2.glGetAttribLocation(mProgram, "position"); + s_gles2.glEnableVertexAttribArray(mPositionSlot); + + mInCoordSlot = s_gles2.glGetAttribLocation(mProgram, "inCoord"); + s_gles2.glEnableVertexAttribArray(mInCoordSlot); + + mTextureSlot = s_gles2.glGetUniformLocation(mProgram, "texture"); + + // Create vertex and index buffers. + s_gles2.glGenBuffers(1, &mVertexBuffer); + s_gles2.glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); + s_gles2.glBufferData(GL_ARRAY_BUFFER, sizeof(kVertices), kVertices, + GL_STATIC_DRAW); + + s_gles2.glGenBuffers(1, &mIndexBuffer); + s_gles2.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer); + s_gles2.glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(kIndices), kIndices, + GL_STATIC_DRAW); +} + +bool TextureDraw::draw(GLuint texture) { + if (!mProgram) { + ERROR(" No program"); + return false; + } + + // TODO(digit): Save previous program state. + + GLenum err; + + s_gles2.glUseProgram(mProgram); + err = s_gles2.glGetError(); + if (err != GL_NO_ERROR) { + ERROR("Could not use program error 0x%x", err); + } + + // Setup the |position| attribute values. + s_gles2.glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); + err = s_gles2.glGetError(); + if (err != GL_NO_ERROR) { + ERROR("Could not bind GL_ARRAY_BUFFER error=0x%x", err); + } + + s_gles2.glEnableVertexAttribArray(mPositionSlot); + s_gles2.glVertexAttribPointer(mPositionSlot, 3, GL_FLOAT, GL_FALSE, + sizeof(Vertex), 0); + err = s_gles2.glGetError(); + if (err != GL_NO_ERROR) { + ERROR("Could glVertexAttribPointer with mPositionSlot error 0x%x", err); + } + + // Setup the |inCoord| attribute values. + s_gles2.glEnableVertexAttribArray(mInCoordSlot); + s_gles2.glVertexAttribPointer( + mInCoordSlot, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), + reinterpret_cast(static_cast(sizeof(float) * 3))); + + // setup the |texture| uniform value. + s_gles2.glActiveTexture(GL_TEXTURE0); + s_gles2.glBindTexture(GL_TEXTURE_2D, texture); + s_gles2.glUniform1i(mTextureSlot, 0); + + // Validate program, just to be sure. + s_gles2.glValidateProgram(mProgram); + GLint validState = 0; + s_gles2.glGetProgramiv(mProgram, GL_VALIDATE_STATUS, &validState); + if (validState == GL_FALSE) { + GLchar messages[256]; + s_gles2.glGetProgramInfoLog(mProgram, sizeof(messages), 0, &messages[0]); + ERROR("Could not run program: %s", messages); + return false; + } + + // Do the rendering. + s_gles2.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer); + err = s_gles2.glGetError(); + if (err != GL_NO_ERROR) { + ERROR("Could not glBindBuffer(GL_ELEMENT_ARRAY_BUFFER) error 0x%x", err); + } + + s_gles2.glDrawElements(GL_TRIANGLES, kIndicesLen, GL_UNSIGNED_BYTE, 0); + err = s_gles2.glGetError(); + if (err != GL_NO_ERROR) { + ERROR("Could not glDrawElements() error 0x%x", err); + } + + // TODO(digit): Restore previous program state. + + return true; +} + +TextureDraw::~TextureDraw() { + s_gles2.glDeleteBuffers(1, &mIndexBuffer); + s_gles2.glDeleteBuffers(1, &mVertexBuffer); + + if (mFragmentShader) { + s_gles2.glDeleteShader(mFragmentShader); + } + if (mVertexShader) { + s_gles2.glDeleteShader(mVertexShader); + } +}