SurfaceFlinger now uses GLES 2.x when available
Bug: 8679321 Change-Id: I2b152d01fb4e2de2ea9fe87f1ddbd6826d7520d7
This commit is contained in:
parent
5ff5a84e48
commit
3f84483382
|
@ -19,8 +19,6 @@
|
|||
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
|
||||
#include <gui/IGraphicBufferProducer.h>
|
||||
#include <gui/BufferQueue.h>
|
||||
|
@ -54,6 +52,8 @@ class String8;
|
|||
* This class was previously called SurfaceTexture.
|
||||
*/
|
||||
class GLConsumer : public ConsumerBase {
|
||||
protected:
|
||||
enum { TEXTURE_EXTERNAL = 0x8D65 }; // GL_TEXTURE_EXTERNAL_OES
|
||||
public:
|
||||
typedef ConsumerBase::FrameAvailableListener FrameAvailableListener;
|
||||
|
||||
|
@ -82,7 +82,7 @@ public:
|
|||
// context to another. If such a transfer is not needed there is no
|
||||
// requirement that either of these methods be called.
|
||||
GLConsumer(const sp<IGraphicBufferConsumer>& bq,
|
||||
GLuint tex, GLenum texTarget = GL_TEXTURE_EXTERNAL_OES,
|
||||
uint32_t tex, uint32_t texureTarget = TEXTURE_EXTERNAL,
|
||||
bool useFenceSync = true, bool isControlledByApp = false);
|
||||
|
||||
// updateTexImage acquires the most recently queued buffer, and sets the
|
||||
|
@ -160,7 +160,7 @@ public:
|
|||
|
||||
// getCurrentTextureTarget returns the texture target of the current
|
||||
// texture as returned by updateTexImage().
|
||||
GLenum getCurrentTextureTarget() const;
|
||||
uint32_t getCurrentTextureTarget() const;
|
||||
|
||||
// getCurrentCrop returns the cropping rectangle of the current buffer.
|
||||
Rect getCurrentCrop() const;
|
||||
|
@ -215,7 +215,7 @@ public:
|
|||
// call to attachToContext will result in this texture object being bound to
|
||||
// the texture target and populated with the image contents that were
|
||||
// current at the time of the last call to detachFromContext.
|
||||
status_t attachToContext(GLuint tex);
|
||||
status_t attachToContext(uint32_t tex);
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -347,7 +347,7 @@ private:
|
|||
// mTexName is the name of the OpenGL texture to which streamed images will
|
||||
// be bound when updateTexImage is called. It is set at construction time
|
||||
// and can be changed with a call to attachToContext.
|
||||
GLuint mTexName;
|
||||
uint32_t mTexName;
|
||||
|
||||
// mUseFenceSync indicates whether creation of the EGL_KHR_fence_sync
|
||||
// extension should be used to prevent buffers from being dequeued before
|
||||
|
@ -362,7 +362,7 @@ private:
|
|||
// glCopyTexSubImage to read from the texture. This is a hack to work
|
||||
// around a GL driver limitation on the number of FBO attachments, which the
|
||||
// browser's tile cache exceeds.
|
||||
const GLenum mTexTarget;
|
||||
const uint32_t mTexTarget;
|
||||
|
||||
// EGLSlot contains the information and object references that
|
||||
// GLConsumer maintains about a BufferQueue buffer slot.
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#define ANDROID_GUI_SURFACE_H
|
||||
|
||||
#include <gui/IGraphicBufferProducer.h>
|
||||
#include <gui/GLConsumer.h>
|
||||
#include <gui/BufferQueue.h>
|
||||
|
||||
#include <ui/ANativeObjectBase.h>
|
||||
|
|
|
@ -89,8 +89,8 @@ static void mtxMul(float out[16], const float a[16], const float b[16]);
|
|||
Mutex GLConsumer::sStaticInitLock;
|
||||
sp<GraphicBuffer> GLConsumer::sReleasedTexImageBuffer;
|
||||
|
||||
GLConsumer::GLConsumer(const sp<IGraphicBufferConsumer>& bq, GLuint tex,
|
||||
GLenum texTarget, bool useFenceSync, bool isControlledByApp) :
|
||||
GLConsumer::GLConsumer(const sp<IGraphicBufferConsumer>& bq, uint32_t tex,
|
||||
uint32_t texTarget, bool useFenceSync, bool isControlledByApp) :
|
||||
ConsumerBase(bq, isControlledByApp),
|
||||
mCurrentTransform(0),
|
||||
mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
|
||||
|
@ -523,7 +523,7 @@ status_t GLConsumer::detachFromContext() {
|
|||
return OK;
|
||||
}
|
||||
|
||||
status_t GLConsumer::attachToContext(GLuint tex) {
|
||||
status_t GLConsumer::attachToContext(uint32_t tex) {
|
||||
ATRACE_CALL();
|
||||
ST_LOGV("attachToContext");
|
||||
Mutex::Autolock lock(mMutex);
|
||||
|
@ -554,7 +554,7 @@ status_t GLConsumer::attachToContext(GLuint tex) {
|
|||
|
||||
// We need to bind the texture regardless of whether there's a current
|
||||
// buffer.
|
||||
glBindTexture(mTexTarget, tex);
|
||||
glBindTexture(mTexTarget, GLuint(tex));
|
||||
|
||||
if (mCurrentTextureBuf != NULL) {
|
||||
// The EGLImageKHR that was associated with the slot was destroyed when
|
||||
|
@ -689,7 +689,7 @@ bool GLConsumer::isExternalFormat(uint32_t format)
|
|||
return false;
|
||||
}
|
||||
|
||||
GLenum GLConsumer::getCurrentTextureTarget() const {
|
||||
uint32_t GLConsumer::getCurrentTextureTarget() const {
|
||||
return mTexTarget;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,10 +19,15 @@ LOCAL_SRC_FILES:= \
|
|||
DisplayHardware/VirtualDisplaySurface.cpp \
|
||||
EventLog/EventLogTags.logtags \
|
||||
EventLog/EventLog.cpp \
|
||||
RenderEngine/Description.cpp \
|
||||
RenderEngine/Mesh.cpp \
|
||||
RenderEngine/Program.cpp \
|
||||
RenderEngine/ProgramCache.cpp \
|
||||
RenderEngine/GLExtensions.cpp \
|
||||
RenderEngine/RenderEngine.cpp \
|
||||
RenderEngine/GLES10RenderEngine.cpp \
|
||||
RenderEngine/GLES11RenderEngine.cpp
|
||||
RenderEngine/GLES11RenderEngine.cpp \
|
||||
RenderEngine/GLES20RenderEngine.cpp
|
||||
|
||||
|
||||
LOCAL_CFLAGS:= -DLOG_TAG=\"SurfaceFlinger\"
|
||||
|
@ -56,6 +61,7 @@ LOCAL_SHARED_LIBRARIES := \
|
|||
libutils \
|
||||
libEGL \
|
||||
libGLESv1_CM \
|
||||
libGLESv2 \
|
||||
libbinder \
|
||||
libui \
|
||||
libgui
|
||||
|
|
|
@ -274,7 +274,7 @@ EGLBoolean DisplayDevice::makeCurrent(EGLDisplay dpy, EGLContext ctx) const {
|
|||
void DisplayDevice::setViewportAndProjection() const {
|
||||
size_t w = mDisplayWidth;
|
||||
size_t h = mDisplayHeight;
|
||||
mFlinger->getRenderEngine().setViewportAndProjection(w, h);
|
||||
mFlinger->getRenderEngine().setViewportAndProjection(w, h, w, h, false);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
|
@ -80,7 +80,7 @@ Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
|
|||
mClientRef(client)
|
||||
{
|
||||
mCurrentCrop.makeInvalid();
|
||||
glGenTextures(1, &mTextureName);
|
||||
mFlinger->getRenderEngine().genTextures(1, &mTextureName);
|
||||
|
||||
uint32_t layerFlags = 0;
|
||||
if (flags & ISurfaceComposerClient::eHidden)
|
||||
|
@ -110,13 +110,10 @@ Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
|
|||
mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
|
||||
}
|
||||
|
||||
void Layer::onFirstRef()
|
||||
{
|
||||
void Layer::onFirstRef() {
|
||||
// Creates a custom BufferQueue for SurfaceFlingerConsumer to use
|
||||
mBufferQueue = new SurfaceTextureLayer(mFlinger);
|
||||
mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mBufferQueue, mTextureName,
|
||||
GL_TEXTURE_EXTERNAL_OES, false);
|
||||
|
||||
mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mBufferQueue, mTextureName);
|
||||
mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
|
||||
mSurfaceFlingerConsumer->setFrameAvailableListener(this);
|
||||
mSurfaceFlingerConsumer->setName(mName);
|
||||
|
@ -495,14 +492,11 @@ void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
|
|||
|
||||
|
||||
void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
|
||||
GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) const
|
||||
float red, float green, float blue, float alpha) const
|
||||
{
|
||||
LayerMesh mesh;
|
||||
computeGeometry(hw, &mesh);
|
||||
|
||||
mFlinger->getRenderEngine().clearWithColor(
|
||||
mesh.getVertices(), mesh.getVertexCount(),
|
||||
red, green, blue, alpha);
|
||||
Mesh mesh(Mesh::TRIANGLE_FAN, 4, 2);
|
||||
computeGeometry(hw, mesh);
|
||||
mFlinger->getRenderEngine().fillWithColor(mesh, red, green, blue, alpha);
|
||||
}
|
||||
|
||||
void Layer::clearWithOpenGL(
|
||||
|
@ -515,8 +509,8 @@ void Layer::drawWithOpenGL(
|
|||
const uint32_t fbHeight = hw->getHeight();
|
||||
const State& s(getDrawingState());
|
||||
|
||||
LayerMesh mesh;
|
||||
computeGeometry(hw, &mesh);
|
||||
Mesh mesh(Mesh::TRIANGLE_FAN, 4, 2, 2);
|
||||
computeGeometry(hw, mesh);
|
||||
|
||||
/*
|
||||
* NOTE: the way we compute the texture coordinates here produces
|
||||
|
@ -534,29 +528,27 @@ void Layer::drawWithOpenGL(
|
|||
*/
|
||||
const Rect win(computeBounds());
|
||||
|
||||
GLfloat left = GLfloat(win.left) / GLfloat(s.active.w);
|
||||
GLfloat top = GLfloat(win.top) / GLfloat(s.active.h);
|
||||
GLfloat right = GLfloat(win.right) / GLfloat(s.active.w);
|
||||
GLfloat bottom = GLfloat(win.bottom) / GLfloat(s.active.h);
|
||||
float left = float(win.left) / float(s.active.w);
|
||||
float top = float(win.top) / float(s.active.h);
|
||||
float right = float(win.right) / float(s.active.w);
|
||||
float bottom = float(win.bottom) / float(s.active.h);
|
||||
|
||||
// TODO: we probably want to generate the texture coords with the mesh
|
||||
// here we assume that we only have 4 vertices
|
||||
float texCoords[4][2];
|
||||
texCoords[0][0] = left;
|
||||
texCoords[0][1] = top;
|
||||
texCoords[1][0] = left;
|
||||
texCoords[1][1] = bottom;
|
||||
texCoords[2][0] = right;
|
||||
texCoords[2][1] = bottom;
|
||||
texCoords[3][0] = right;
|
||||
texCoords[3][1] = top;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
texCoords[i][1] = 1.0f - texCoords[i][1];
|
||||
}
|
||||
size_t stride = mesh.getStride();
|
||||
float* base = mesh.getTexCoords();
|
||||
base[stride*0 + 0] = left;
|
||||
base[stride*0 + 1] = 1.0f - top;
|
||||
base[stride*1 + 0] = left;
|
||||
base[stride*1 + 1] = 1.0f - bottom;
|
||||
base[stride*2 + 0] = right;
|
||||
base[stride*2 + 1] = 1.0f - bottom;
|
||||
base[stride*3 + 0] = right;
|
||||
base[stride*3 + 1] = 1.0f - top;
|
||||
|
||||
RenderEngine& engine(mFlinger->getRenderEngine());
|
||||
engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(), s.alpha);
|
||||
engine.drawMesh2D(mesh.getVertices(), texCoords, mesh.getVertexCount());
|
||||
engine.drawMesh(mesh);
|
||||
engine.disableBlending();
|
||||
}
|
||||
|
||||
|
@ -592,7 +584,7 @@ bool Layer::getOpacityForFormat(uint32_t format) {
|
|||
// local state
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void Layer::computeGeometry(const sp<const DisplayDevice>& hw, LayerMesh* mesh) const
|
||||
void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh) const
|
||||
{
|
||||
const Layer::State& s(getDrawingState());
|
||||
const Transform tr(hw->getTransform() * s.transform);
|
||||
|
@ -603,14 +595,13 @@ void Layer::computeGeometry(const sp<const DisplayDevice>& hw, LayerMesh* mesh)
|
|||
}
|
||||
// subtract the transparent region and snap to the bounds
|
||||
win = reduce(win, s.activeTransparentRegion);
|
||||
if (mesh) {
|
||||
tr.transform(mesh->mVertices[0], win.left, win.top);
|
||||
tr.transform(mesh->mVertices[1], win.left, win.bottom);
|
||||
tr.transform(mesh->mVertices[2], win.right, win.bottom);
|
||||
tr.transform(mesh->mVertices[3], win.right, win.top);
|
||||
for (size_t i=0 ; i<4 ; i++) {
|
||||
mesh->mVertices[i][1] = hw_h - mesh->mVertices[i][1];
|
||||
}
|
||||
|
||||
tr.transform(mesh[0], win.left, win.top);
|
||||
tr.transform(mesh[1], win.left, win.bottom);
|
||||
tr.transform(mesh[2], win.right, win.bottom);
|
||||
tr.transform(mesh[3], win.right, win.top);
|
||||
for (size_t i=0 ; i<4 ; i++) {
|
||||
mesh[i][1] = hw_h - mesh[i][1];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1195,6 +1186,12 @@ Layer::LayerCleaner::~LayerCleaner() {
|
|||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
}; // namespace android
|
||||
|
||||
#if defined(__gl_h_)
|
||||
#error "don't include gl/gl.h in this file"
|
||||
#endif
|
||||
|
||||
#if defined(__gl2_h_)
|
||||
#error "don't include gl2/gl2.h in this file"
|
||||
#endif
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
|
||||
#include "DisplayHardware/HWComposer.h"
|
||||
#include "DisplayHardware/FloatRect.h"
|
||||
#include "RenderEngine/Mesh.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
|
@ -109,23 +110,6 @@ public:
|
|||
Region requestedTransparentRegion;
|
||||
};
|
||||
|
||||
class LayerMesh {
|
||||
friend class Layer;
|
||||
typedef GLfloat float2[2];
|
||||
float2 mVertices[4];
|
||||
size_t mNumVertices;
|
||||
public:
|
||||
LayerMesh() :
|
||||
mNumVertices(4) {
|
||||
}
|
||||
float2 const* getVertices() const {
|
||||
return mVertices;
|
||||
}
|
||||
size_t getVertexCount() const {
|
||||
return mNumVertices;
|
||||
}
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
Layer(SurfaceFlinger* flinger, const sp<Client>& client,
|
||||
|
@ -150,7 +134,7 @@ public:
|
|||
uint32_t getTransactionFlags(uint32_t flags);
|
||||
uint32_t setTransactionFlags(uint32_t flags);
|
||||
|
||||
void computeGeometry(const sp<const DisplayDevice>& hw, LayerMesh* mesh) const;
|
||||
void computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh) const;
|
||||
Rect computeBounds() const;
|
||||
|
||||
sp<IBinder> getHandle();
|
||||
|
@ -336,7 +320,7 @@ private:
|
|||
|
||||
// drawing
|
||||
void clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
|
||||
GLclampf r, GLclampf g, GLclampf b, GLclampf alpha) const;
|
||||
float r, float g, float b, float alpha) const;
|
||||
void drawWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip) const;
|
||||
|
||||
|
||||
|
@ -345,7 +329,7 @@ private:
|
|||
// constants
|
||||
sp<SurfaceFlingerConsumer> mSurfaceFlingerConsumer;
|
||||
sp<BufferQueue> mBufferQueue;
|
||||
GLuint mTextureName;
|
||||
uint32_t mTextureName;
|
||||
bool mPremultipliedAlpha;
|
||||
String8 mName;
|
||||
mutable bool mDebug;
|
||||
|
|
|
@ -43,11 +43,11 @@ void LayerDim::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) con
|
|||
{
|
||||
const State& s(getDrawingState());
|
||||
if (s.alpha>0) {
|
||||
LayerMesh mesh;
|
||||
computeGeometry(hw, &mesh);
|
||||
Mesh mesh(Mesh::TRIANGLE_FAN, 4, 2);
|
||||
computeGeometry(hw, mesh);
|
||||
RenderEngine& engine(mFlinger->getRenderEngine());
|
||||
engine.setupDimLayerBlending(s.alpha);
|
||||
engine.drawMesh2D(mesh.getVertices(), NULL, mesh.getVertexCount());
|
||||
engine.drawMesh(mesh);
|
||||
engine.disableBlending();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* Copyright 2013 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 <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <utils/TypeHelpers.h>
|
||||
|
||||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
|
||||
#include "Description.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
Description::Description() :
|
||||
mUniformsDirty(true) {
|
||||
mPlaneAlpha = 1.0f;
|
||||
mPremultipliedAlpha = true;
|
||||
mOpaque = true;
|
||||
mTextureTarget = GL_TEXTURE_EXTERNAL_OES;
|
||||
|
||||
const GLfloat m[16] = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 };
|
||||
memset(mColor, 0, sizeof(mColor));
|
||||
memcpy(mProjectionMatrix, m, sizeof(mProjectionMatrix));
|
||||
memcpy(mTextureMatrix, m, sizeof(mTextureMatrix));
|
||||
}
|
||||
|
||||
Description::~Description() {
|
||||
}
|
||||
|
||||
void Description::setPlaneAlpha(GLclampf planeAlpha) {
|
||||
if (planeAlpha != mPlaneAlpha) {
|
||||
mUniformsDirty = true;
|
||||
mPlaneAlpha = planeAlpha;
|
||||
}
|
||||
}
|
||||
|
||||
void Description::setPremultipliedAlpha(bool premultipliedAlpha) {
|
||||
if (premultipliedAlpha != mPremultipliedAlpha) {
|
||||
mPremultipliedAlpha = premultipliedAlpha;
|
||||
}
|
||||
}
|
||||
|
||||
void Description::setOpaque(bool opaque) {
|
||||
if (opaque != mOpaque) {
|
||||
mOpaque = opaque;
|
||||
}
|
||||
}
|
||||
|
||||
void Description::setTextureName(GLenum target, GLuint tname) {
|
||||
if (target != mTextureTarget) {
|
||||
mTextureTarget = target;
|
||||
}
|
||||
if (tname != mTextureName) {
|
||||
mTextureName = tname;
|
||||
mUniformsDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Description::disableTexture() {
|
||||
if (mTextureTarget != 0) {
|
||||
mTextureTarget = 0;
|
||||
}
|
||||
mTextureName = 0;
|
||||
}
|
||||
|
||||
void Description::setColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {
|
||||
mColor[0] = red;
|
||||
mColor[1] = green;
|
||||
mColor[2] = blue;
|
||||
mColor[3] = alpha;
|
||||
mUniformsDirty = true;
|
||||
}
|
||||
|
||||
void Description::setProjectionMatrix(GLfloat const* mtx) {
|
||||
memcpy(mProjectionMatrix, mtx, sizeof(mProjectionMatrix));
|
||||
mUniformsDirty = true;
|
||||
}
|
||||
|
||||
void Description::setTextureMatrix(GLfloat const* mtx) {
|
||||
memcpy(mTextureMatrix, mtx, sizeof(mTextureMatrix));
|
||||
mUniformsDirty = true;
|
||||
}
|
||||
|
||||
} /* namespace android */
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright 2013 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 <GLES2/gl2.h>
|
||||
|
||||
#ifndef SF_RENDER_ENGINE_DESCRIPTION_H_
|
||||
#define SF_RENDER_ENGINE_DESCRIPTION_H_
|
||||
|
||||
namespace android {
|
||||
|
||||
class Program;
|
||||
|
||||
/*
|
||||
* This holds the state of the rendering engine. This class is used
|
||||
* to generate a corresponding GLSL program and set the appropriate
|
||||
* uniform.
|
||||
*
|
||||
* Program and ProgramCache are friends and access the state directly
|
||||
*/
|
||||
class Description {
|
||||
friend class Program;
|
||||
friend class ProgramCache;
|
||||
|
||||
// value of the plane-alpha, between 0 and 1
|
||||
GLclampf mPlaneAlpha;
|
||||
// whether textures are premultiplied
|
||||
bool mPremultipliedAlpha;
|
||||
// whether this layer is marked as opaque
|
||||
bool mOpaque;
|
||||
// texture target, TEXTURE_2D or TEXTURE_EXTERNAL
|
||||
GLenum mTextureTarget;
|
||||
|
||||
// name of the texture
|
||||
GLuint mTextureName;
|
||||
// color used when texturing is disabled
|
||||
GLclampf mColor[4];
|
||||
// projection matrix
|
||||
GLfloat mProjectionMatrix[16];
|
||||
// texture matrix
|
||||
GLfloat mTextureMatrix[16];
|
||||
|
||||
public:
|
||||
Description();
|
||||
~Description();
|
||||
|
||||
void setPlaneAlpha(GLclampf planeAlpha);
|
||||
void setPremultipliedAlpha(bool premultipliedAlpha);
|
||||
void setOpaque(bool opaque);
|
||||
void setTextureName(GLenum target, GLuint tname);
|
||||
void disableTexture();
|
||||
void setColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
|
||||
void setProjectionMatrix(GLfloat const* mtx);
|
||||
void setTextureMatrix(GLfloat const* mtx);
|
||||
|
||||
private:
|
||||
bool mUniformsDirty;
|
||||
};
|
||||
|
||||
} /* namespace android */
|
||||
|
||||
#endif /* SF_RENDER_ENGINE_DESCRIPTION_H_ */
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "GLES11RenderEngine.h"
|
||||
#include "GLExtensions.h"
|
||||
#include "Mesh.h"
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
namespace android {
|
||||
|
@ -69,12 +70,14 @@ size_t GLES11RenderEngine::getMaxViewportDims() const {
|
|||
mMaxViewportDims[0] : mMaxViewportDims[1];
|
||||
}
|
||||
|
||||
void GLES11RenderEngine::setViewportAndProjection(size_t w, size_t h) {
|
||||
glViewport(0, 0, w, h);
|
||||
void GLES11RenderEngine::setViewportAndProjection(
|
||||
size_t vpw, size_t vph, size_t w, size_t h, bool yswap) {
|
||||
glViewport(0, 0, vpw, vph);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
// put the origin in the left-bottom corner
|
||||
glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h
|
||||
if (yswap) glOrthof(0, w, h, 0, 0, 1);
|
||||
else glOrthof(0, w, 0, h, 0, 1);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
|
||||
|
@ -87,7 +90,7 @@ void GLES11RenderEngine::setupLayerBlending(
|
|||
|
||||
if (CC_UNLIKELY(alpha < 0xFF)) {
|
||||
// Cv = premultiplied ? Cs*alpha : Cs
|
||||
// Av = !opaque ? alpha*As : 1.0
|
||||
// Av = !opaque ? As*alpha : As
|
||||
combineRGB = premultipliedAlpha ? GL_MODULATE : GL_REPLACE;
|
||||
combineAlpha = !opaque ? GL_MODULATE : GL_REPLACE;
|
||||
src0Alpha = GL_CONSTANT;
|
||||
|
@ -180,25 +183,37 @@ void GLES11RenderEngine::disableBlending() {
|
|||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
void GLES11RenderEngine::clearWithColor(const float vertices[][2] , size_t count,
|
||||
float red, float green, float blue, float alpha) {
|
||||
glColor4f(red, green, blue, alpha);
|
||||
void GLES11RenderEngine::fillWithColor(const Mesh& mesh, float r, float g, float b, float a) {
|
||||
glColor4f(r, g, b, a);
|
||||
glDisable(GL_TEXTURE_EXTERNAL_OES);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glDisable(GL_BLEND);
|
||||
glVertexPointer(2, GL_FLOAT, 0, vertices);
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, count);
|
||||
|
||||
glVertexPointer(mesh.getVertexSize(),
|
||||
GL_FLOAT,
|
||||
mesh.getByteStride(),
|
||||
mesh.getVertices());
|
||||
|
||||
glDrawArrays(mesh.getPrimitive(), 0, mesh.getVertexCount());
|
||||
}
|
||||
|
||||
void GLES11RenderEngine::drawMesh2D(
|
||||
const float vertices[][2], const float texCoords[][2], size_t count) {
|
||||
if (texCoords) {
|
||||
void GLES11RenderEngine::drawMesh(const Mesh& mesh) {
|
||||
if (mesh.getTexCoordsSize()) {
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
|
||||
glTexCoordPointer(mesh.getTexCoordsSize(),
|
||||
GL_FLOAT,
|
||||
mesh.getByteStride(),
|
||||
mesh.getTexCoords());
|
||||
}
|
||||
glVertexPointer(2, GL_FLOAT, 0, vertices);
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, count);
|
||||
if (texCoords) {
|
||||
|
||||
glVertexPointer(mesh.getVertexSize(),
|
||||
GL_FLOAT,
|
||||
mesh.getByteStride(),
|
||||
mesh.getVertices());
|
||||
|
||||
glDrawArrays(mesh.getPrimitive(), 0, mesh.getVertexCount());
|
||||
|
||||
if (mesh.getTexCoordsSize()) {
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ namespace android {
|
|||
// ---------------------------------------------------------------------------
|
||||
|
||||
class String8;
|
||||
class Mesh;
|
||||
|
||||
class GLES11RenderEngine : public RenderEngine {
|
||||
GLuint mProtectedTexName;
|
||||
|
@ -43,7 +44,7 @@ protected:
|
|||
virtual ~GLES11RenderEngine();
|
||||
|
||||
virtual void dump(String8& result);
|
||||
virtual void setViewportAndProjection(size_t w, size_t h);
|
||||
virtual void setViewportAndProjection(size_t vpw, size_t vph, size_t w, size_t h, bool yswap);
|
||||
virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, int alpha);
|
||||
virtual void setupDimLayerBlending(int alpha);
|
||||
virtual void setupLayerTexturing(size_t textureName, bool useFiltering, const float* textureMatrix);
|
||||
|
@ -51,10 +52,8 @@ protected:
|
|||
virtual void disableTexturing();
|
||||
virtual void disableBlending();
|
||||
|
||||
virtual void clearWithColor(const float vertices[][2], size_t count,
|
||||
float red, float green, float blue, float alpha);
|
||||
|
||||
virtual void drawMesh2D(const float vertices[][2], const float texCoords[][2], size_t count);
|
||||
virtual void fillWithColor(const Mesh& mesh, float r, float g, float b, float a) ;
|
||||
virtual void drawMesh(const Mesh& mesh);
|
||||
|
||||
virtual size_t getMaxTextureSize() const;
|
||||
virtual size_t getMaxViewportDims() const;
|
||||
|
|
|
@ -0,0 +1,213 @@
|
|||
/*
|
||||
* Copyright 2013 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.
|
||||
*/
|
||||
|
||||
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
|
||||
|
||||
#include <GLES2/gl2.h>
|
||||
|
||||
#include <utils/String8.h>
|
||||
#include <utils/Trace.h>
|
||||
|
||||
#include <cutils/compiler.h>
|
||||
|
||||
#include "GLES20RenderEngine.h"
|
||||
#include "GLExtensions.h"
|
||||
#include "Program.h"
|
||||
#include "ProgramCache.h"
|
||||
#include "Description.h"
|
||||
#include "Mesh.h"
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
namespace android {
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
GLES20RenderEngine::GLES20RenderEngine() {
|
||||
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
|
||||
glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims);
|
||||
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 4);
|
||||
|
||||
struct pack565 {
|
||||
inline uint16_t operator() (int r, int g, int b) const {
|
||||
return (r<<11)|(g<<5)|b;
|
||||
}
|
||||
} pack565;
|
||||
|
||||
const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) };
|
||||
glGenTextures(1, &mProtectedTexName);
|
||||
glBindTexture(GL_TEXTURE_2D, mProtectedTexName);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0,
|
||||
GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData);
|
||||
}
|
||||
|
||||
GLES20RenderEngine::~GLES20RenderEngine() {
|
||||
}
|
||||
|
||||
|
||||
size_t GLES20RenderEngine::getMaxTextureSize() const {
|
||||
return mMaxTextureSize;
|
||||
}
|
||||
|
||||
size_t GLES20RenderEngine::getMaxViewportDims() const {
|
||||
return
|
||||
mMaxViewportDims[0] < mMaxViewportDims[1] ?
|
||||
mMaxViewportDims[0] : mMaxViewportDims[1];
|
||||
}
|
||||
|
||||
void GLES20RenderEngine::setViewportAndProjection(
|
||||
size_t vpw, size_t vph, size_t w, size_t h, bool yswap) {
|
||||
|
||||
struct ortho {
|
||||
inline void operator() (GLfloat *m,
|
||||
GLfloat left, GLfloat right, GLfloat bottom, GLfloat top,
|
||||
GLfloat near, GLfloat far) const {
|
||||
memset(m, 0, 16*sizeof(GLfloat));
|
||||
m[ 0] = 2.0f / (right - left);
|
||||
m[ 5] = 2.0f / (top - bottom);
|
||||
m[10] =-2.0f / (far - near);
|
||||
m[15] = 1.0f;
|
||||
m[12] = -(right + left) / (right - left);
|
||||
m[13] = -(top + bottom) / (top - bottom);
|
||||
m[14] = -(far + near) / (far - near);
|
||||
}
|
||||
} ortho;
|
||||
|
||||
GLfloat m[16];
|
||||
if (yswap) ortho(m, 0, w, h, 0, 0, 1);
|
||||
else ortho(m, 0, w, 0, h, 0, 1);
|
||||
|
||||
glViewport(0, 0, vpw, vph);
|
||||
mState.setProjectionMatrix(m);
|
||||
}
|
||||
|
||||
void GLES20RenderEngine::setupLayerBlending(
|
||||
bool premultipliedAlpha, bool opaque, int alpha) {
|
||||
|
||||
mState.setPremultipliedAlpha(premultipliedAlpha);
|
||||
mState.setOpaque(opaque);
|
||||
mState.setPlaneAlpha(alpha / 255.0f);
|
||||
|
||||
if (alpha < 0xFF || !opaque) {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(premultipliedAlpha ? GL_ONE : GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
} else {
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
}
|
||||
|
||||
void GLES20RenderEngine::setupDimLayerBlending(int alpha) {
|
||||
mState.setPlaneAlpha(alpha / 255.0f);
|
||||
|
||||
if (alpha == 0xFF) {
|
||||
glDisable(GL_BLEND);
|
||||
} else {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
disableTexturing();
|
||||
}
|
||||
|
||||
void GLES20RenderEngine::setupLayerTexturing(size_t textureName,
|
||||
bool useFiltering, const float* textureMatrix) {
|
||||
glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureName);
|
||||
GLenum filter = GL_NEAREST;
|
||||
if (useFiltering) {
|
||||
filter = GL_LINEAR;
|
||||
}
|
||||
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter);
|
||||
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter);
|
||||
|
||||
mState.setTextureName(GL_TEXTURE_EXTERNAL_OES, textureName);
|
||||
mState.setTextureMatrix(textureMatrix);
|
||||
}
|
||||
|
||||
void GLES20RenderEngine::setupLayerBlackedOut() {
|
||||
const GLfloat m[16] = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 };
|
||||
glBindTexture(GL_TEXTURE_2D, mProtectedTexName);
|
||||
mState.setTextureName(GL_TEXTURE_2D, mProtectedTexName);
|
||||
mState.setTextureMatrix(m);
|
||||
}
|
||||
|
||||
void GLES20RenderEngine::disableTexturing() {
|
||||
mState.disableTexture();
|
||||
}
|
||||
|
||||
void GLES20RenderEngine::disableBlending() {
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
void GLES20RenderEngine::fillWithColor(const Mesh& mesh, float r, float g, float b, float a) {
|
||||
mState.setColor(r, g, b, a);
|
||||
disableTexturing();
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
ProgramCache::getInstance().useProgram(mState);
|
||||
|
||||
glVertexAttribPointer(Program::position,
|
||||
mesh.getVertexSize(),
|
||||
GL_FLOAT, GL_FALSE,
|
||||
mesh.getByteStride(),
|
||||
mesh.getVertices());
|
||||
|
||||
glDrawArrays(mesh.getPrimitive(), 0, mesh.getVertexCount());
|
||||
}
|
||||
|
||||
void GLES20RenderEngine::drawMesh(const Mesh& mesh) {
|
||||
|
||||
ProgramCache::getInstance().useProgram(mState);
|
||||
|
||||
if (mesh.getTexCoordsSize()) {
|
||||
glEnableVertexAttribArray(Program::texCoords);
|
||||
glVertexAttribPointer(Program::texCoords,
|
||||
mesh.getTexCoordsSize(),
|
||||
GL_FLOAT, GL_FALSE,
|
||||
mesh.getByteStride(),
|
||||
mesh.getTexCoords());
|
||||
}
|
||||
|
||||
glVertexAttribPointer(Program::position,
|
||||
mesh.getVertexSize(),
|
||||
GL_FLOAT, GL_FALSE,
|
||||
mesh.getByteStride(),
|
||||
mesh.getVertices());
|
||||
|
||||
glDrawArrays(mesh.getPrimitive(), 0, mesh.getVertexCount());
|
||||
|
||||
if (mesh.getTexCoordsSize()) {
|
||||
glDisableVertexAttribArray(Program::texCoords);
|
||||
}
|
||||
}
|
||||
|
||||
void GLES20RenderEngine::dump(String8& result) {
|
||||
const GLExtensions& extensions(GLExtensions::getInstance());
|
||||
result.appendFormat("GLES: %s, %s, %s\n",
|
||||
extensions.getVendor(),
|
||||
extensions.getRenderer(),
|
||||
extensions.getVersion());
|
||||
result.appendFormat("%s\n", extensions.getExtension());
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
}; // namespace android
|
||||
// ---------------------------------------------------------------------------
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright 2013 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.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SF_GLES20RENDERENGINE_H_
|
||||
#define SF_GLES20RENDERENGINE_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <GLES2/gl2.h>
|
||||
|
||||
#include "RenderEngine.h"
|
||||
#include "ProgramCache.h"
|
||||
#include "Description.h"
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
namespace android {
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
class String8;
|
||||
class Mesh;
|
||||
|
||||
class GLES20RenderEngine : public RenderEngine {
|
||||
GLuint mProtectedTexName;
|
||||
GLint mMaxViewportDims[2];
|
||||
GLint mMaxTextureSize;
|
||||
|
||||
Description mState;
|
||||
|
||||
public:
|
||||
GLES20RenderEngine();
|
||||
|
||||
protected:
|
||||
virtual ~GLES20RenderEngine();
|
||||
|
||||
virtual void dump(String8& result);
|
||||
virtual void setViewportAndProjection(size_t vpw, size_t vph, size_t w, size_t h, bool yswap);
|
||||
virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, int alpha);
|
||||
virtual void setupDimLayerBlending(int alpha);
|
||||
virtual void setupLayerTexturing(size_t textureName, bool useFiltering, const float* textureMatrix);
|
||||
virtual void setupLayerBlackedOut();
|
||||
virtual void disableTexturing();
|
||||
virtual void disableBlending();
|
||||
|
||||
virtual void fillWithColor(const Mesh& mesh, float r, float g, float b, float a);
|
||||
virtual void drawMesh(const Mesh& mesh);
|
||||
|
||||
virtual size_t getMaxTextureSize() const;
|
||||
virtual size_t getMaxViewportDims() const;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
}; // namespace android
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#endif /* SF_GLES20RENDERENGINE_H_ */
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright 2013 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 "Mesh.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
Mesh::Mesh(Primitive primitive, size_t vertexCount, size_t vertexSize, size_t texCoordSize)
|
||||
: mVertexCount(vertexCount), mVertexSize(vertexSize), mTexCoordsSize(texCoordSize),
|
||||
mPrimitive(primitive)
|
||||
{
|
||||
mVertices = new float[(vertexSize + texCoordSize) * vertexCount];
|
||||
mStride = mVertexSize + mTexCoordsSize;
|
||||
}
|
||||
|
||||
Mesh::~Mesh() {
|
||||
delete [] mVertices;
|
||||
}
|
||||
|
||||
float const* Mesh::operator[](size_t index) const {
|
||||
return &mVertices[index * mStride];
|
||||
}
|
||||
|
||||
float* Mesh::operator[](size_t index) {
|
||||
return &mVertices[index * mStride];
|
||||
}
|
||||
|
||||
Mesh::Primitive Mesh::getPrimitive() const {
|
||||
return mPrimitive;
|
||||
}
|
||||
|
||||
|
||||
float const* Mesh::getVertices() const {
|
||||
return mVertices;
|
||||
}
|
||||
float* Mesh::getVertices() {
|
||||
return mVertices;
|
||||
}
|
||||
|
||||
float const* Mesh::getTexCoords() const {
|
||||
return mVertices + mVertexSize;
|
||||
}
|
||||
float* Mesh::getTexCoords() {
|
||||
return mVertices + mVertexSize;
|
||||
}
|
||||
|
||||
|
||||
size_t Mesh::getVertexCount() const {
|
||||
return mVertexCount;
|
||||
}
|
||||
|
||||
size_t Mesh::getVertexSize() const {
|
||||
return mVertexSize;
|
||||
}
|
||||
|
||||
size_t Mesh::getTexCoordsSize() const {
|
||||
return mTexCoordsSize;
|
||||
}
|
||||
|
||||
size_t Mesh::getByteStride() const {
|
||||
return mStride*sizeof(float);
|
||||
}
|
||||
|
||||
size_t Mesh::getStride() const {
|
||||
return mStride;
|
||||
}
|
||||
|
||||
} /* namespace android */
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright 2013 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.
|
||||
*/
|
||||
|
||||
#ifndef SF_RENDER_ENGINE_MESH_H
|
||||
#define SF_RENDER_ENGINE_MESH_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
class Mesh {
|
||||
public:
|
||||
enum Primitive {
|
||||
TRIANGLES = 0x0004,
|
||||
TRIANGLE_STRIP = 0x0005,
|
||||
TRIANGLE_FAN = 0x0006
|
||||
};
|
||||
|
||||
Mesh(Primitive primitive, size_t vertexCount, size_t vertexSize, size_t texCoordsSize = 0);
|
||||
~Mesh();
|
||||
|
||||
float const* operator[](size_t index) const;
|
||||
float* operator[](size_t index);
|
||||
|
||||
|
||||
Primitive getPrimitive() const;
|
||||
|
||||
float const* getVertices() const;
|
||||
float* getVertices();
|
||||
|
||||
float const* getTexCoords() const;
|
||||
float* getTexCoords();
|
||||
|
||||
size_t getVertexCount() const;
|
||||
size_t getVertexSize() const;
|
||||
size_t getTexCoordsSize() const;
|
||||
|
||||
size_t getByteStride() const;
|
||||
size_t getStride() const;
|
||||
|
||||
private:
|
||||
float* mVertices;
|
||||
size_t mVertexCount;
|
||||
size_t mVertexSize;
|
||||
size_t mTexCoordsSize;
|
||||
size_t mStride;
|
||||
Primitive mPrimitive;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace android */
|
||||
#endif /* SF_RENDER_ENGINE_MESH_H */
|
|
@ -0,0 +1,144 @@
|
|||
/*Gluint
|
||||
* Copyright 2013 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 <stdint.h>
|
||||
|
||||
#include <log/log.h>
|
||||
|
||||
#include "Program.h"
|
||||
#include "ProgramCache.h"
|
||||
#include "Description.h"
|
||||
#include <utils/String8.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
Program::Program(const ProgramCache::Key& needs, const char* vertex, const char* fragment)
|
||||
: mInitialized(false) {
|
||||
GLuint vertexId = buildShader(vertex, GL_VERTEX_SHADER);
|
||||
GLuint fragmentId = buildShader(fragment, GL_FRAGMENT_SHADER);
|
||||
GLuint programId = glCreateProgram();
|
||||
glAttachShader(programId, vertexId);
|
||||
glAttachShader(programId, fragmentId);
|
||||
glBindAttribLocation(programId, position, "position");
|
||||
glBindAttribLocation(programId, texCoords, "texCoords");
|
||||
glLinkProgram(programId);
|
||||
|
||||
GLint status;
|
||||
glGetProgramiv(programId, GL_LINK_STATUS, &status);
|
||||
if (status != GL_TRUE) {
|
||||
ALOGE("Error while linking shaders:");
|
||||
GLint infoLen = 0;
|
||||
glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &infoLen);
|
||||
if (infoLen > 1) {
|
||||
GLchar log[infoLen];
|
||||
glGetProgramInfoLog(programId, infoLen, 0, &log[0]);
|
||||
ALOGE("%s", log);
|
||||
}
|
||||
glDetachShader(programId, vertexId);
|
||||
glDetachShader(programId, fragmentId);
|
||||
glDeleteShader(vertexId);
|
||||
glDeleteShader(fragmentId);
|
||||
glDeleteProgram(programId);
|
||||
} else {
|
||||
mProgram = programId;
|
||||
mVertexShader = vertexId;
|
||||
mFragmentShader = fragmentId;
|
||||
mInitialized = true;
|
||||
|
||||
mProjectionMatrixLoc = glGetUniformLocation(programId, "projection");
|
||||
mTextureMatrixLoc = glGetUniformLocation(programId, "texture");
|
||||
mSamplerLoc = glGetUniformLocation(programId, "sampler");
|
||||
mColorLoc = glGetUniformLocation(programId, "color");
|
||||
mAlphaPlaneLoc = glGetUniformLocation(programId, "alphaPlane");
|
||||
|
||||
// set-up the default values for our uniforms
|
||||
glUseProgram(programId);
|
||||
const GLfloat m[16] = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 };
|
||||
glUniformMatrix4fv(mProjectionMatrixLoc, 1, GL_FALSE, m);
|
||||
glEnableVertexAttribArray(0);
|
||||
}
|
||||
}
|
||||
|
||||
Program::~Program() {
|
||||
}
|
||||
|
||||
bool Program::isValid() const {
|
||||
return mInitialized;
|
||||
}
|
||||
|
||||
void Program::use() {
|
||||
glUseProgram(mProgram);
|
||||
}
|
||||
|
||||
GLuint Program::getAttrib(const char* name) const {
|
||||
// TODO: maybe use a local cache
|
||||
return glGetAttribLocation(mProgram, name);
|
||||
}
|
||||
|
||||
GLint Program::getUniform(const char* name) const {
|
||||
// TODO: maybe use a local cache
|
||||
return glGetUniformLocation(mProgram, 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);
|
||||
ALOGE("Error while compiling shader: \n%s\n%s", source, log);
|
||||
glDeleteShader(shader);
|
||||
return 0;
|
||||
}
|
||||
return shader;
|
||||
}
|
||||
|
||||
String8& Program::dumpShader(String8& result, GLenum type) {
|
||||
GLuint shader = GL_FRAGMENT_SHADER ? mFragmentShader : mVertexShader;
|
||||
GLint l;
|
||||
glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &l);
|
||||
char* src = new char[l];
|
||||
glGetShaderSource(shader, l, NULL, src);
|
||||
result.append(src);
|
||||
delete [] src;
|
||||
return result;
|
||||
}
|
||||
|
||||
void Program::setUniforms(const Description& desc) {
|
||||
|
||||
// TODO: we should have a mechanism here to not always reset uniforms that
|
||||
// didn't change for this program.
|
||||
|
||||
if (mSamplerLoc >= 0) {
|
||||
glUniform1i(mSamplerLoc, 0);
|
||||
glUniformMatrix4fv(mTextureMatrixLoc, 1, GL_FALSE, desc.mTextureMatrix);
|
||||
}
|
||||
if (mAlphaPlaneLoc >= 0) {
|
||||
glUniform1f(mAlphaPlaneLoc, desc.mPlaneAlpha);
|
||||
}
|
||||
if (mColorLoc >= 0) {
|
||||
glUniform4fv(mColorLoc, 1, desc.mColor);
|
||||
}
|
||||
// these uniforms are always present
|
||||
glUniformMatrix4fv(mProjectionMatrixLoc, 1, GL_FALSE, desc.mProjectionMatrix);
|
||||
}
|
||||
|
||||
} /* namespace android */
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright 2013 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.
|
||||
*/
|
||||
|
||||
#ifndef SF_RENDER_ENGINE_PROGRAM_H
|
||||
#define SF_RENDER_ENGINE_PROGRAM_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <GLES2/gl2.h>
|
||||
|
||||
#include "Description.h"
|
||||
#include "ProgramCache.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
class String8;
|
||||
|
||||
/*
|
||||
* Abstracts a GLSL program comprising a vertex and fragment shader
|
||||
*/
|
||||
class Program {
|
||||
public:
|
||||
// known locations for position and texture coordinates
|
||||
enum { position=0, texCoords=1 };
|
||||
|
||||
Program(const ProgramCache::Key& needs, const char* vertex, const char* fragment);
|
||||
~Program();
|
||||
|
||||
/* whether this object is usable */
|
||||
bool isValid() const;
|
||||
|
||||
/* Binds this program to the GLES context */
|
||||
void use();
|
||||
|
||||
/* Returns the location of the specified attribute */
|
||||
GLuint getAttrib(const char* name) const;
|
||||
|
||||
/* Returns the location of the specified uniform */
|
||||
GLint getUniform(const char* name) const;
|
||||
|
||||
/* set-up uniforms from the description */
|
||||
void setUniforms(const Description& desc);
|
||||
|
||||
|
||||
private:
|
||||
GLuint buildShader(const char* source, GLenum type);
|
||||
String8& dumpShader(String8& result, GLenum type);
|
||||
|
||||
// whether the initialization succeeded
|
||||
bool mInitialized;
|
||||
|
||||
// Name of the OpenGL program and shaders
|
||||
GLuint mProgram;
|
||||
GLuint mVertexShader;
|
||||
GLuint mFragmentShader;
|
||||
|
||||
/* location of the projection matrix uniform */
|
||||
GLint mProjectionMatrixLoc;
|
||||
|
||||
/* location of the texture matrix uniform */
|
||||
GLint mTextureMatrixLoc;
|
||||
|
||||
/* location of the sampler uniform */
|
||||
GLint mSamplerLoc;
|
||||
|
||||
/* location of the alpha plane uniform */
|
||||
GLint mAlphaPlaneLoc;
|
||||
|
||||
/* location of the color uniform */
|
||||
GLint mColorLoc;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace android */
|
||||
|
||||
#endif /* SF_RENDER_ENGINE_PROGRAM_H */
|
|
@ -0,0 +1,206 @@
|
|||
/*
|
||||
* Copyright 2013 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 <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
|
||||
#include <utils/String8.h>
|
||||
|
||||
#include "ProgramCache.h"
|
||||
#include "Program.h"
|
||||
#include "Description.h"
|
||||
|
||||
namespace android {
|
||||
// -----------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
/*
|
||||
* A simple formatter class to automatically add the endl and
|
||||
* manage the indentation.
|
||||
*/
|
||||
|
||||
class Formatter;
|
||||
static Formatter& indent(Formatter& f);
|
||||
static Formatter& dedent(Formatter& f);
|
||||
|
||||
class Formatter {
|
||||
String8 mString;
|
||||
int mIndent;
|
||||
typedef Formatter& (*FormaterManipFunc)(Formatter&);
|
||||
friend Formatter& indent(Formatter& f);
|
||||
friend Formatter& dedent(Formatter& f);
|
||||
public:
|
||||
String8 getString() const {
|
||||
return mString;
|
||||
}
|
||||
|
||||
friend Formatter& operator << (Formatter& out, const char* in) {
|
||||
for (int i=0 ; i<out.mIndent ; i++) {
|
||||
out.mString.append(" ");
|
||||
}
|
||||
out.mString.append(in);
|
||||
out.mString.append("\n");
|
||||
return out;
|
||||
}
|
||||
friend inline Formatter& operator << (Formatter& out, const String8& in) {
|
||||
return operator << (out, in.string());
|
||||
}
|
||||
friend inline Formatter& operator<<(Formatter& to, FormaterManipFunc func) {
|
||||
return (*func)(to);
|
||||
}
|
||||
};
|
||||
Formatter& indent(Formatter& f) {
|
||||
f.mIndent++;
|
||||
return f;
|
||||
}
|
||||
Formatter& dedent(Formatter& f) {
|
||||
f.mIndent--;
|
||||
return f;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------
|
||||
|
||||
ANDROID_SINGLETON_STATIC_INSTANCE(ProgramCache)
|
||||
|
||||
|
||||
ProgramCache::ProgramCache() {
|
||||
}
|
||||
|
||||
ProgramCache::~ProgramCache() {
|
||||
}
|
||||
|
||||
ProgramCache::Key ProgramCache::computeKey(const Description& description) {
|
||||
Key needs;
|
||||
needs.set(Key::TEXTURE_MASK,
|
||||
(description.mTextureTarget == GL_TEXTURE_EXTERNAL_OES) ? Key::TEXTURE_EXT :
|
||||
(description.mTextureTarget == GL_TEXTURE_2D) ? Key::TEXTURE_2D :
|
||||
Key::TEXTURE_OFF)
|
||||
.set(Key::PLANE_ALPHA_MASK,
|
||||
(description.mPlaneAlpha < 1) ? Key::PLANE_ALPHA_LT_ONE : Key::PLANE_ALPHA_EQ_ONE)
|
||||
.set(Key::BLEND_MASK,
|
||||
description.mPremultipliedAlpha ? Key::BLEND_PREMULT : Key::BLEND_NORMAL)
|
||||
.set(Key::OPACITY_MASK,
|
||||
description.mOpaque ? Key::OPACITY_OPAQUE : Key::OPACITY_TRANSLUCENT);
|
||||
return needs;
|
||||
}
|
||||
|
||||
String8 ProgramCache::generateVertexShader(const Key& needs) {
|
||||
Formatter vs;
|
||||
if (needs.isTexturing()) {
|
||||
vs << "attribute vec4 texCoords;"
|
||||
<< "varying vec2 outTexCoords;";
|
||||
}
|
||||
vs << "attribute vec4 position;"
|
||||
<< "uniform mat4 projection;"
|
||||
<< "uniform mat4 texture;"
|
||||
<< "void main(void) {" << indent
|
||||
<< "gl_Position = projection * position;";
|
||||
if (needs.isTexturing()) {
|
||||
vs << "outTexCoords = (texture * texCoords).st;";
|
||||
}
|
||||
vs << dedent << "}";
|
||||
return vs.getString();
|
||||
}
|
||||
|
||||
String8 ProgramCache::generateFragmentShader(const Key& needs) {
|
||||
Formatter fs;
|
||||
if (needs.getTextureTarget() == Key::TEXTURE_EXT) {
|
||||
fs << "#extension GL_OES_EGL_image_external : require";
|
||||
}
|
||||
if (needs.getTextureTarget() == Key::TEXTURE_EXT) {
|
||||
fs << "uniform samplerExternalOES sampler;"
|
||||
<< "varying vec2 outTexCoords;";
|
||||
} else if (needs.getTextureTarget() == Key::TEXTURE_2D) {
|
||||
fs << "uniform sampler2D sampler;"
|
||||
<< "varying vec2 outTexCoords;";
|
||||
} else if (needs.getTextureTarget() == Key::TEXTURE_OFF) {
|
||||
fs << "uniform vec4 color;";
|
||||
}
|
||||
if (needs.hasPlaneAlpha()) {
|
||||
fs << "uniform float alphaPlane;";
|
||||
}
|
||||
fs << "void main(void) {" << indent;
|
||||
if (needs.isTexturing()) {
|
||||
fs << "gl_FragColor = texture2D(sampler, outTexCoords);";
|
||||
} else {
|
||||
fs << "gl_FragColor = color;";
|
||||
}
|
||||
if (needs.hasPlaneAlpha()) {
|
||||
// modulate the alpha value with planeAlpha
|
||||
if (needs.isPremultiplied()) {
|
||||
// ... and the color too if we're premultiplied
|
||||
if (needs.isOpaque()) {
|
||||
// ... we're opaque, only premultiply the color component
|
||||
fs << "gl_FragColor.rgb *= alphaPlane;"
|
||||
<< "gl_FragColor.a = alphaPlane;";
|
||||
} else {
|
||||
fs << "gl_FragColor *= alphaPlane;";
|
||||
}
|
||||
} else {
|
||||
// not premultiplied
|
||||
if (needs.isOpaque()) {
|
||||
fs << "gl_FragColor.a = alphaPlane;";
|
||||
} else {
|
||||
fs << "gl_FragColor.a *= alphaPlane;";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (needs.isOpaque()) {
|
||||
fs << "gl_FragColor.a = 1.0;";
|
||||
}
|
||||
}
|
||||
fs << dedent << "}";
|
||||
return fs.getString();
|
||||
}
|
||||
|
||||
Program* ProgramCache::generateProgram(const Key& needs) {
|
||||
// vertex shader
|
||||
String8 vs = generateVertexShader(needs);
|
||||
|
||||
// fragment shader
|
||||
String8 fs = generateFragmentShader(needs);
|
||||
|
||||
Program* program = new Program(needs, vs.string(), fs.string());
|
||||
return program;
|
||||
}
|
||||
|
||||
void ProgramCache::useProgram(const Description& description) {
|
||||
|
||||
// generate the key for the shader based on the description
|
||||
Key needs(computeKey(description));
|
||||
|
||||
// look-up the program in the cache
|
||||
Program* program = mCache.valueFor(needs);
|
||||
if (program == NULL) {
|
||||
// we didn't find our program, so generate one...
|
||||
nsecs_t time = -systemTime();
|
||||
program = generateProgram(needs);
|
||||
mCache.add(needs, program);
|
||||
time += systemTime();
|
||||
|
||||
//ALOGD(">>> generated new program: needs=%08X, time=%u ms (%d programs)",
|
||||
// needs.mNeeds, uint32_t(ns2ms(time)), mCache.size());
|
||||
}
|
||||
|
||||
// here we have a suitable program for this description
|
||||
if (program->isValid()) {
|
||||
program->use();
|
||||
program->setUniforms(description);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} /* namespace android */
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* Copyright 2013 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.
|
||||
*/
|
||||
|
||||
#ifndef SF_RENDER_ENGINE_PROGRAMCACHE_H
|
||||
#define SF_RENDER_ENGINE_PROGRAMCACHE_H
|
||||
|
||||
#include <GLES2/gl2.h>
|
||||
|
||||
#include <utils/Singleton.h>
|
||||
#include <utils/KeyedVector.h>
|
||||
#include <utils/TypeHelpers.h>
|
||||
|
||||
#include "Description.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
class Description;
|
||||
class Program;
|
||||
class String8;
|
||||
|
||||
/*
|
||||
* This class generates GLSL programs suitable to handle a given
|
||||
* Description. It's responsible for figuring out what to
|
||||
* generate from a Description.
|
||||
* It also maintains a cache of these Programs.
|
||||
*/
|
||||
class ProgramCache : public Singleton<ProgramCache> {
|
||||
public:
|
||||
/*
|
||||
* Key is used to retrieve a Program in the cache.
|
||||
* A Key is generated from a Description.
|
||||
*/
|
||||
class Key {
|
||||
friend class ProgramCache;
|
||||
typedef uint32_t key_t;
|
||||
key_t mKey;
|
||||
public:
|
||||
enum {
|
||||
BLEND_PREMULT = 0x00000001,
|
||||
BLEND_NORMAL = 0x00000000,
|
||||
BLEND_MASK = 0x00000001,
|
||||
|
||||
OPACITY_OPAQUE = 0x00000002,
|
||||
OPACITY_TRANSLUCENT = 0x00000000,
|
||||
OPACITY_MASK = 0x00000002,
|
||||
|
||||
PLANE_ALPHA_LT_ONE = 0x00000004,
|
||||
PLANE_ALPHA_EQ_ONE = 0x00000000,
|
||||
PLANE_ALPHA_MASK = 0x00000004,
|
||||
|
||||
TEXTURE_OFF = 0x00000000,
|
||||
TEXTURE_EXT = 0x00000008,
|
||||
TEXTURE_2D = 0x00000010,
|
||||
TEXTURE_MASK = 0x00000018,
|
||||
};
|
||||
|
||||
inline Key() : mKey(0) { }
|
||||
inline Key(const Key& rhs) : mKey(rhs.mKey) { }
|
||||
|
||||
inline Key& set(key_t mask, key_t value) {
|
||||
mKey = (mKey & ~mask) | value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool isTexturing() const {
|
||||
return (mKey & TEXTURE_MASK) != TEXTURE_OFF;
|
||||
}
|
||||
inline int getTextureTarget() const {
|
||||
return (mKey & TEXTURE_MASK);
|
||||
}
|
||||
inline bool isPremultiplied() const {
|
||||
return (mKey & BLEND_MASK) == BLEND_PREMULT;
|
||||
}
|
||||
inline bool isOpaque() const {
|
||||
return (mKey & OPACITY_MASK) == OPACITY_OPAQUE;
|
||||
}
|
||||
inline bool hasPlaneAlpha() const {
|
||||
return (mKey & PLANE_ALPHA_MASK) == PLANE_ALPHA_LT_ONE;
|
||||
}
|
||||
|
||||
// this is the definition of a friend function -- not a method of class Needs
|
||||
friend inline int strictly_order_type(const Key& lhs, const Key& rhs) {
|
||||
return (lhs.mKey < rhs.mKey) ? 1 : 0;
|
||||
}
|
||||
};
|
||||
|
||||
ProgramCache();
|
||||
~ProgramCache();
|
||||
|
||||
// useProgram lookup a suitable program in the cache or generates one
|
||||
// if none can be found.
|
||||
void useProgram(const Description& description);
|
||||
|
||||
private:
|
||||
// compute a cache Key from a Description
|
||||
static Key computeKey(const Description& description);
|
||||
// generates a program from the Key
|
||||
static Program* generateProgram(const Key& needs);
|
||||
// generates the vertex shader from the Key
|
||||
static String8 generateVertexShader(const Key& needs);
|
||||
// generates the fragment shader from the Key
|
||||
static String8 generateFragmentShader(const Key& needs);
|
||||
|
||||
// Key/Value map used for caching Programs. Currently the cache
|
||||
// is never shrunk.
|
||||
DefaultKeyedVector<Key, Program*> mCache;
|
||||
};
|
||||
|
||||
|
||||
ANDROID_BASIC_TYPES_TRAITS(ProgramCache::Key)
|
||||
|
||||
} /* namespace android */
|
||||
|
||||
#endif /* SF_RENDER_ENGINE_PROGRAMCACHE_H */
|
|
@ -15,11 +15,15 @@
|
|||
*/
|
||||
|
||||
#include <cutils/log.h>
|
||||
#include <ui/Rect.h>
|
||||
#include <ui/Region.h>
|
||||
|
||||
#include "RenderEngine.h"
|
||||
#include "GLES10RenderEngine.h"
|
||||
#include "GLES11RenderEngine.h"
|
||||
#include "GLES20RenderEngine.h"
|
||||
#include "GLExtensions.h"
|
||||
#include "Mesh.h"
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
namespace android {
|
||||
|
@ -28,7 +32,7 @@ namespace android {
|
|||
RenderEngine* RenderEngine::create(EGLDisplay display, EGLConfig config) {
|
||||
// Also create our EGLContext
|
||||
EGLint contextAttributes[] = {
|
||||
// EGL_CONTEXT_CLIENT_VERSION, 2,
|
||||
EGL_CONTEXT_CLIENT_VERSION, 2, // MUST be first
|
||||
#ifdef EGL_IMG_context_priority
|
||||
#ifdef HAS_CONTEXT_PRIORITY
|
||||
#warning "using EGL_IMG_context_priority"
|
||||
|
@ -79,7 +83,7 @@ RenderEngine* RenderEngine::create(EGLDisplay display, EGLConfig config) {
|
|||
break;
|
||||
case GLES_VERSION_2_0:
|
||||
case GLES_VERSION_3_0:
|
||||
//engine = new GLES20RenderEngine();
|
||||
engine = new GLES20RenderEngine();
|
||||
break;
|
||||
}
|
||||
engine->setEGLContext(ctxt);
|
||||
|
@ -140,6 +144,85 @@ RenderEngine::GlesVersion RenderEngine::parseGlesVersion(const char* str) {
|
|||
return GLES_VERSION_1_0;
|
||||
}
|
||||
|
||||
void RenderEngine::fillRegionWithColor(const Region& region, uint32_t height,
|
||||
float red, float green, float blue, float alpha) {
|
||||
size_t c;
|
||||
Rect const* r = region.getArray(&c);
|
||||
Mesh mesh(Mesh::TRIANGLES, c*6, 2);
|
||||
for (size_t i=0 ; i<c ; i++, r++) {
|
||||
mesh[i*6 + 0][0] = r->left;
|
||||
mesh[i*6 + 0][1] = height - r->top;
|
||||
mesh[i*6 + 1][0] = r->left;
|
||||
mesh[i*6 + 1][1] = height - r->bottom;
|
||||
mesh[i*6 + 2][0] = r->right;
|
||||
mesh[i*6 + 2][1] = height - r->bottom;
|
||||
mesh[i*6 + 3][0] = r->left;
|
||||
mesh[i*6 + 3][1] = height - r->top;
|
||||
mesh[i*6 + 4][0] = r->right;
|
||||
mesh[i*6 + 4][1] = height - r->bottom;
|
||||
mesh[i*6 + 5][0] = r->right;
|
||||
mesh[i*6 + 5][1] = height - r->top;
|
||||
}
|
||||
fillWithColor(mesh, red, green, blue, alpha);
|
||||
}
|
||||
|
||||
void RenderEngine::clearWithColor(float red, float green, float blue, float alpha) {
|
||||
glClearColor(red, green, blue, alpha);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void RenderEngine::setScissor(
|
||||
uint32_t left, uint32_t bottom, uint32_t right, uint32_t top) {
|
||||
glScissor(left, bottom, right, top);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
void RenderEngine::disableScissor() {
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
void RenderEngine::genTextures(size_t count, uint32_t* names) {
|
||||
glGenTextures(count, names);
|
||||
}
|
||||
|
||||
void RenderEngine::deleteTextures(size_t count, uint32_t const* names) {
|
||||
glDeleteTextures(count, names);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
RenderEngine::BindImageAsFramebuffer::BindImageAsFramebuffer(
|
||||
RenderEngine& engine, EGLImageKHR image) : mEngine(engine)
|
||||
{
|
||||
GLuint tname, name;
|
||||
// turn our EGLImage into a texture
|
||||
glGenTextures(1, &tname);
|
||||
glBindTexture(GL_TEXTURE_2D, tname);
|
||||
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);
|
||||
// create a Framebuffer Object to render into
|
||||
glGenFramebuffersOES(1, &name);
|
||||
glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
|
||||
glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
|
||||
GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
|
||||
mStatus = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
|
||||
ALOGE_IF(mStatus != GL_FRAMEBUFFER_COMPLETE_OES,
|
||||
"glCheckFramebufferStatusOES error %d", mStatus);
|
||||
mTexName = tname;
|
||||
mFbName = name;
|
||||
}
|
||||
|
||||
RenderEngine::BindImageAsFramebuffer::~BindImageAsFramebuffer() {
|
||||
// back to main framebuffer
|
||||
glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
|
||||
glDeleteFramebuffersOES(1, &mFbName);
|
||||
glDeleteTextures(1, &mTexName);
|
||||
|
||||
}
|
||||
|
||||
status_t RenderEngine::BindImageAsFramebuffer::getStatus() const {
|
||||
return mStatus == GL_FRAMEBUFFER_COMPLETE_OES ? NO_ERROR : BAD_VALUE;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
}; // namespace android
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
|
@ -22,12 +22,16 @@
|
|||
#include <sys/types.h>
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
namespace android {
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
class String8;
|
||||
class Rect;
|
||||
class Region;
|
||||
class Mesh;
|
||||
|
||||
class RenderEngine {
|
||||
enum GlesVersion {
|
||||
|
@ -48,10 +52,31 @@ protected:
|
|||
public:
|
||||
static RenderEngine* create(EGLDisplay display, EGLConfig config);
|
||||
|
||||
virtual void checkErrors() const;
|
||||
// helpers
|
||||
void clearWithColor(float red, float green, float blue, float alpha);
|
||||
void fillRegionWithColor(const Region& region, uint32_t height,
|
||||
float red, float green, float blue, float alpha);
|
||||
|
||||
// common to all GL versions
|
||||
void setScissor(uint32_t left, uint32_t bottom, uint32_t right, uint32_t top);
|
||||
void disableScissor();
|
||||
void genTextures(size_t count, uint32_t* names);
|
||||
void deleteTextures(size_t count, uint32_t const* names);
|
||||
|
||||
class BindImageAsFramebuffer {
|
||||
RenderEngine& mEngine;
|
||||
unsigned int mTexName, mFbName;
|
||||
unsigned int mStatus;
|
||||
public:
|
||||
BindImageAsFramebuffer(RenderEngine& engine, EGLImageKHR image);
|
||||
~BindImageAsFramebuffer();
|
||||
int getStatus() const;
|
||||
};
|
||||
|
||||
// set-up
|
||||
virtual void checkErrors() const;
|
||||
virtual void dump(String8& result) = 0;
|
||||
virtual void setViewportAndProjection(size_t w, size_t h) = 0;
|
||||
virtual void setViewportAndProjection(size_t vpw, size_t vph, size_t w, size_t h, bool yswap) = 0;
|
||||
virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, int alpha) = 0;
|
||||
virtual void setupDimLayerBlending(int alpha) = 0;
|
||||
virtual void setupLayerTexturing(size_t textureName, bool useFiltering, const float* textureMatrix) = 0;
|
||||
|
@ -60,14 +85,16 @@ public:
|
|||
virtual void disableTexturing() = 0;
|
||||
virtual void disableBlending() = 0;
|
||||
|
||||
virtual void clearWithColor(const float vertices[][2], size_t count,
|
||||
float red, float green, float blue, float alpha) = 0;
|
||||
|
||||
virtual void drawMesh2D(const float vertices[][2], const float texCoords[][2], size_t count) = 0;
|
||||
// drawing
|
||||
virtual void fillWithColor(const Mesh& mesh, float r, float g, float b, float a) = 0;
|
||||
virtual void drawMesh(const Mesh& mesh) = 0;
|
||||
|
||||
// queries
|
||||
virtual size_t getMaxTextureSize() const = 0;
|
||||
virtual size_t getMaxViewportDims() const = 0;
|
||||
|
||||
|
||||
|
||||
EGLContext getEGLContext() const;
|
||||
};
|
||||
|
||||
|
|
|
@ -23,8 +23,6 @@
|
|||
#include <dlfcn.h>
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <GLES/gl.h>
|
||||
#include <GLES/glext.h>
|
||||
|
||||
#include <cutils/log.h>
|
||||
#include <cutils/properties.h>
|
||||
|
@ -72,6 +70,7 @@
|
|||
|
||||
#include "RenderEngine/RenderEngine.h"
|
||||
|
||||
|
||||
#define DISPLAY_COUNT 1
|
||||
|
||||
/*
|
||||
|
@ -268,19 +267,20 @@ void SurfaceFlinger::bootFinished()
|
|||
property_set("service.bootanim.exit", "1");
|
||||
}
|
||||
|
||||
void SurfaceFlinger::deleteTextureAsync(GLuint texture) {
|
||||
void SurfaceFlinger::deleteTextureAsync(uint32_t texture) {
|
||||
class MessageDestroyGLTexture : public MessageBase {
|
||||
GLuint texture;
|
||||
RenderEngine& engine;
|
||||
uint32_t texture;
|
||||
public:
|
||||
MessageDestroyGLTexture(GLuint texture)
|
||||
: texture(texture) {
|
||||
MessageDestroyGLTexture(RenderEngine& engine, uint32_t texture)
|
||||
: engine(engine), texture(texture) {
|
||||
}
|
||||
virtual bool handler() {
|
||||
glDeleteTextures(1, &texture);
|
||||
engine.deleteTextures(1, &texture);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
postMessageAsync(new MessageDestroyGLTexture(texture));
|
||||
postMessageAsync(new MessageDestroyGLTexture(getRenderEngine(), texture));
|
||||
}
|
||||
|
||||
status_t SurfaceFlinger::selectConfigForAttribute(
|
||||
|
@ -750,24 +750,10 @@ void SurfaceFlinger::doDebugFlashRegions()
|
|||
doComposeSurfaces(hw, Region(hw->bounds()));
|
||||
|
||||
// and draw the dirty region
|
||||
glDisable(GL_TEXTURE_EXTERNAL_OES);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glDisable(GL_BLEND);
|
||||
glColor4f(1, 0, 1, 1);
|
||||
const int32_t height = hw->getHeight();
|
||||
Region::const_iterator it = dirtyRegion.begin();
|
||||
Region::const_iterator const end = dirtyRegion.end();
|
||||
while (it != end) {
|
||||
const Rect& r = *it++;
|
||||
GLfloat vertices[][2] = {
|
||||
{ (GLfloat) r.left, (GLfloat) (height - r.top) },
|
||||
{ (GLfloat) r.left, (GLfloat) (height - r.bottom) },
|
||||
{ (GLfloat) r.right, (GLfloat) (height - r.bottom) },
|
||||
{ (GLfloat) r.right, (GLfloat) (height - r.top) }
|
||||
};
|
||||
glVertexPointer(2, GL_FLOAT, 0, vertices);
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
}
|
||||
RenderEngine& engine(getRenderEngine());
|
||||
engine.fillRegionWithColor(dirtyRegion, height, 1, 0, 1, 1);
|
||||
|
||||
hw->compositionComplete();
|
||||
hw->swapBuffers(getHwComposer());
|
||||
}
|
||||
|
@ -1512,6 +1498,7 @@ void SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw,
|
|||
|
||||
void SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty)
|
||||
{
|
||||
RenderEngine& engine(getRenderEngine());
|
||||
const int32_t id = hw->getHwcDisplayId();
|
||||
HWComposer& hwc(getHwComposer());
|
||||
HWComposer::LayerListIterator cur = hwc.begin(id);
|
||||
|
@ -1525,20 +1512,15 @@ void SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const
|
|||
return;
|
||||
}
|
||||
|
||||
// set the frame buffer
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
// Never touch the framebuffer if we don't have any framebuffer layers
|
||||
const bool hasHwcComposition = hwc.hasHwcComposition(id);
|
||||
if (hasHwcComposition) {
|
||||
// when using overlays, we assume a fully transparent framebuffer
|
||||
// NOTE: we could reduce how much we need to clear, for instance
|
||||
// remove where there are opaque FB layers. however, on some
|
||||
// GPUs doing a "clean slate" glClear might be more efficient.
|
||||
// GPUs doing a "clean slate" clear might be more efficient.
|
||||
// We'll revisit later if needed.
|
||||
glClearColor(0, 0, 0, 0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
engine.clearWithColor(0, 0, 0, 0);
|
||||
} else {
|
||||
// we start with the whole screen area
|
||||
const Region bounds(hw->getBounds());
|
||||
|
@ -1571,11 +1553,11 @@ void SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const
|
|||
// scissor doesn't match the screen's dimensions, so we
|
||||
// need to clear everything outside of it and enable
|
||||
// the GL scissor so we don't draw anything where we shouldn't
|
||||
const GLint height = hw->getHeight();
|
||||
glScissor(scissor.left, height - scissor.bottom,
|
||||
scissor.getWidth(), scissor.getHeight());
|
||||
|
||||
// enable scissor for this frame
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
const uint32_t height = hw->getHeight();
|
||||
engine.setScissor(scissor.left, height - scissor.bottom,
|
||||
scissor.getWidth(), scissor.getHeight());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1632,31 +1614,13 @@ void SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const
|
|||
}
|
||||
|
||||
// disable scissor at the end of the frame
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
engine.disableScissor();
|
||||
}
|
||||
|
||||
void SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& hw,
|
||||
const Region& region) const
|
||||
{
|
||||
glDisable(GL_TEXTURE_EXTERNAL_OES);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glDisable(GL_BLEND);
|
||||
glColor4f(0,0,0,0);
|
||||
|
||||
void SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& hw, const Region& region) const {
|
||||
const int32_t height = hw->getHeight();
|
||||
Region::const_iterator it = region.begin();
|
||||
Region::const_iterator const end = region.end();
|
||||
while (it != end) {
|
||||
const Rect& r = *it++;
|
||||
GLfloat vertices[][2] = {
|
||||
{ (GLfloat) r.left, (GLfloat) (height - r.top) },
|
||||
{ (GLfloat) r.left, (GLfloat) (height - r.bottom) },
|
||||
{ (GLfloat) r.right, (GLfloat) (height - r.bottom) },
|
||||
{ (GLfloat) r.right, (GLfloat) (height - r.top) }
|
||||
};
|
||||
glVertexPointer(2, GL_FLOAT, 0, vertices);
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
}
|
||||
RenderEngine& engine(getRenderEngine());
|
||||
engine.fillRegionWithColor(region, height, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
void SurfaceFlinger::addClientLayer(const sp<Client>& client,
|
||||
|
@ -1673,8 +1637,7 @@ void SurfaceFlinger::addClientLayer(const sp<Client>& client,
|
|||
mGraphicBufferProducerList.add(gbc->asBinder());
|
||||
}
|
||||
|
||||
status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer)
|
||||
{
|
||||
status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
|
||||
Mutex::Autolock _l(mStateLock);
|
||||
ssize_t index = mCurrentState.layersSortedByZ.remove(layer);
|
||||
if (index >= 0) {
|
||||
|
@ -1686,18 +1649,15 @@ status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer)
|
|||
return status_t(index);
|
||||
}
|
||||
|
||||
uint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags)
|
||||
{
|
||||
uint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags) {
|
||||
return android_atomic_release_load(&mTransactionFlags);
|
||||
}
|
||||
|
||||
uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
|
||||
{
|
||||
uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) {
|
||||
return android_atomic_and(~flags, &mTransactionFlags) & flags;
|
||||
}
|
||||
|
||||
uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
|
||||
{
|
||||
uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) {
|
||||
uint32_t old = android_atomic_or(flags, &mTransactionFlags);
|
||||
if ((old & flags)==0) { // wake the server up
|
||||
signalTransaction();
|
||||
|
@ -2739,31 +2699,22 @@ void SurfaceFlinger::renderScreenImplLocked(
|
|||
bool yswap)
|
||||
{
|
||||
ATRACE_CALL();
|
||||
RenderEngine& engine(getRenderEngine());
|
||||
|
||||
// get screen geometry
|
||||
const uint32_t hw_w = hw->getWidth();
|
||||
const uint32_t hw_h = hw->getHeight();
|
||||
|
||||
const bool filtering = reqWidth != hw_w || reqWidth != hw_h;
|
||||
|
||||
// make sure to clear all GL error flags
|
||||
while ( glGetError() != GL_NO_ERROR ) ;
|
||||
engine.checkErrors();
|
||||
|
||||
// set-up our viewport
|
||||
glViewport(0, 0, reqWidth, reqHeight);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
if (yswap) glOrthof(0, hw_w, hw_h, 0, 0, 1);
|
||||
else glOrthof(0, hw_w, 0, hw_h, 0, 1);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
engine.setViewportAndProjection(reqWidth, reqHeight, hw_w, hw_h, yswap);
|
||||
engine.disableTexturing();
|
||||
|
||||
// redraw the screen entirely...
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glClearColor(0,0,0,1);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glDisable(GL_TEXTURE_EXTERNAL_OES);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
engine.clearWithColor(0, 0, 0, 1);
|
||||
|
||||
const LayerVector& layers( mDrawingState.layersSortedByZ );
|
||||
const size_t count = layers.size();
|
||||
|
@ -2834,20 +2785,10 @@ status_t SurfaceFlinger::captureScreenImplLocked(
|
|||
EGLImageKHR image = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT,
|
||||
EGL_NATIVE_BUFFER_ANDROID, buffer, NULL);
|
||||
if (image != EGL_NO_IMAGE_KHR) {
|
||||
GLuint tname, name;
|
||||
|
||||
// turn our EGLImage into a texture
|
||||
glGenTextures(1, &tname);
|
||||
glBindTexture(GL_TEXTURE_2D, tname);
|
||||
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);
|
||||
// create a Framebuffer Object to render into
|
||||
glGenFramebuffersOES(1, &name);
|
||||
glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
|
||||
glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
|
||||
GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
|
||||
|
||||
GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
|
||||
if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
|
||||
// this binds the given EGLImage as a framebuffer for the
|
||||
// duration of this scope.
|
||||
RenderEngine::BindImageAsFramebuffer imageBond(getRenderEngine(), image);
|
||||
if (imageBond.getStatus() == NO_ERROR) {
|
||||
// this will in fact render into our dequeued buffer
|
||||
// via an FBO, which means we didn't have to create
|
||||
// an EGLSurface and therefore we're not
|
||||
|
@ -2858,12 +2799,6 @@ status_t SurfaceFlinger::captureScreenImplLocked(
|
|||
ALOGE("got GL_FRAMEBUFFER_COMPLETE_OES error while taking screenshot");
|
||||
result = INVALID_OPERATION;
|
||||
}
|
||||
|
||||
// back to main framebuffer
|
||||
glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
|
||||
glDeleteFramebuffersOES(1, &name);
|
||||
glDeleteTextures(1, &tname);
|
||||
|
||||
// destroy our image
|
||||
eglDestroyImageKHR(mEGLDisplay, image);
|
||||
} else {
|
||||
|
@ -2955,3 +2890,12 @@ SurfaceFlinger::DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayTyp
|
|||
// ---------------------------------------------------------------------------
|
||||
|
||||
}; // namespace android
|
||||
|
||||
|
||||
#if defined(__gl_h_)
|
||||
#error "don't include gl/gl.h in this file"
|
||||
#endif
|
||||
|
||||
#if defined(__gl2_h_)
|
||||
#error "don't include gl2/gl2.h in this file"
|
||||
#endif
|
||||
|
|
|
@ -21,7 +21,10 @@
|
|||
#include <sys/types.h>
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <GLES/gl.h> // needed for GLuint
|
||||
|
||||
/*
|
||||
* NOTE: Make sure this file doesn't include anything from <gl/ > or <gl2/ >
|
||||
*/
|
||||
|
||||
#include <cutils/compiler.h>
|
||||
|
||||
|
@ -91,12 +94,10 @@ public:
|
|||
};
|
||||
|
||||
// post an asynchronous message to the main thread
|
||||
status_t postMessageAsync(const sp<MessageBase>& msg, nsecs_t reltime = 0,
|
||||
uint32_t flags = 0);
|
||||
status_t postMessageAsync(const sp<MessageBase>& msg, nsecs_t reltime = 0, uint32_t flags = 0);
|
||||
|
||||
// post a synchronous message to the main thread
|
||||
status_t postMessageSync(const sp<MessageBase>& msg, nsecs_t reltime = 0,
|
||||
uint32_t flags = 0);
|
||||
status_t postMessageSync(const sp<MessageBase>& msg, nsecs_t reltime = 0, uint32_t flags = 0);
|
||||
|
||||
// force full composition on all displays
|
||||
void repaintEverything();
|
||||
|
@ -107,7 +108,7 @@ public:
|
|||
}
|
||||
|
||||
// utility function to delete a texture on the main thread
|
||||
void deleteTextureAsync(GLuint texture);
|
||||
void deleteTextureAsync(uint32_t texture);
|
||||
|
||||
// enable/disable h/w composer event
|
||||
// TODO: this should be made accessible only to EventThread
|
||||
|
@ -254,8 +255,7 @@ private:
|
|||
uint32_t peekTransactionFlags(uint32_t flags);
|
||||
uint32_t setTransactionFlags(uint32_t flags);
|
||||
void commitTransaction();
|
||||
uint32_t setClientStateLocked(const sp<Client>& client,
|
||||
const layer_state_t& s);
|
||||
uint32_t setClientStateLocked(const sp<Client>& client, const layer_state_t& s);
|
||||
uint32_t setDisplayStateLocked(const DisplayState& s);
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
|
@ -365,14 +365,11 @@ private:
|
|||
void setUpHWComposer();
|
||||
void doComposition();
|
||||
void doDebugFlashRegions();
|
||||
void doDisplayComposition(const sp<const DisplayDevice>& hw,
|
||||
const Region& dirtyRegion);
|
||||
void doComposeSurfaces(const sp<const DisplayDevice>& hw,
|
||||
const Region& dirty);
|
||||
void doDisplayComposition(const sp<const DisplayDevice>& hw, const Region& dirtyRegion);
|
||||
void doComposeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty);
|
||||
|
||||
void postFramebuffer();
|
||||
void drawWormhole(const sp<const DisplayDevice>& hw,
|
||||
const Region& region) const;
|
||||
void drawWormhole(const sp<const DisplayDevice>& hw, const Region& region) const;
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
* Display management
|
||||
|
@ -382,14 +379,10 @@ private:
|
|||
/* ------------------------------------------------------------------------
|
||||
* Debugging & dumpsys
|
||||
*/
|
||||
void listLayersLocked(const Vector<String16>& args, size_t& index,
|
||||
String8& result) const;
|
||||
void dumpStatsLocked(const Vector<String16>& args, size_t& index,
|
||||
String8& result) const;
|
||||
void clearStatsLocked(const Vector<String16>& args, size_t& index,
|
||||
String8& result);
|
||||
void dumpAllLocked(const Vector<String16>& args, size_t& index,
|
||||
String8& result) const;
|
||||
void listLayersLocked(const Vector<String16>& args, size_t& index, String8& result) const;
|
||||
void dumpStatsLocked(const Vector<String16>& args, size_t& index, String8& result) const;
|
||||
void clearStatsLocked(const Vector<String16>& args, size_t& index, String8& result);
|
||||
void dumpAllLocked(const Vector<String16>& args, size_t& index, String8& result) const;
|
||||
bool startDdmConnection();
|
||||
static void appendSfConfigString(String8& result);
|
||||
void checkScreenshot(const sp<GraphicBuffer>& buf, void const* vaddr,
|
||||
|
|
|
@ -53,8 +53,6 @@ status_t SurfaceFlingerConsumer::updateTexImage(BufferRejecter* rejecter)
|
|||
err = acquireBufferLocked(&item, computeExpectedPresent());
|
||||
if (err != NO_ERROR) {
|
||||
if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
|
||||
// This variant of updateTexImage does not guarantee that the
|
||||
// texture is bound, so no need to call glBindTexture.
|
||||
err = NO_ERROR;
|
||||
} else if (err == BufferQueue::PRESENT_LATER) {
|
||||
// return the error, without logging
|
||||
|
|
|
@ -27,10 +27,8 @@ namespace android {
|
|||
*/
|
||||
class SurfaceFlingerConsumer : public GLConsumer {
|
||||
public:
|
||||
SurfaceFlingerConsumer(const sp<BufferQueue>& bq, GLuint tex,
|
||||
GLenum texTarget = GL_TEXTURE_EXTERNAL_OES,
|
||||
bool useFenceSync = true)
|
||||
: GLConsumer(bq, tex, texTarget, useFenceSync)
|
||||
SurfaceFlingerConsumer(const sp<BufferQueue>& bq, uint32_t tex)
|
||||
: GLConsumer(bq, tex, GLConsumer::TEXTURE_EXTERNAL, false)
|
||||
{}
|
||||
|
||||
class BufferRejecter {
|
||||
|
|
Loading…
Reference in New Issue