diff --git a/include/gui/GLConsumer.h b/include/gui/GLConsumer.h index 891c464aa..00f38b44b 100644 --- a/include/gui/GLConsumer.h +++ b/include/gui/GLConsumer.h @@ -19,8 +19,6 @@ #include #include -#include -#include #include #include @@ -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& 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. diff --git a/include/gui/Surface.h b/include/gui/Surface.h index 2f7406e2b..6f8a97c80 100644 --- a/include/gui/Surface.h +++ b/include/gui/Surface.h @@ -18,7 +18,6 @@ #define ANDROID_GUI_SURFACE_H #include -#include #include #include diff --git a/libs/gui/GLConsumer.cpp b/libs/gui/GLConsumer.cpp index 482317f2d..0a2afbf9b 100644 --- a/libs/gui/GLConsumer.cpp +++ b/libs/gui/GLConsumer.cpp @@ -89,8 +89,8 @@ static void mtxMul(float out[16], const float a[16], const float b[16]); Mutex GLConsumer::sStaticInitLock; sp GLConsumer::sReleasedTexImageBuffer; -GLConsumer::GLConsumer(const sp& bq, GLuint tex, - GLenum texTarget, bool useFenceSync, bool isControlledByApp) : +GLConsumer::GLConsumer(const sp& 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; } diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk index 8dbb9c5a7..7a14fb05f 100644 --- a/services/surfaceflinger/Android.mk +++ b/services/surfaceflinger/Android.mk @@ -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 diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp index 8143227d7..79b6689c8 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -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); } // ---------------------------------------------------------------------------- diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 2defe34db..cf4ec57eb 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -80,7 +80,7 @@ Layer::Layer(SurfaceFlinger* flinger, const sp& 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, 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& hw, const Region& clip) const void Layer::clearWithOpenGL(const sp& 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& hw, LayerMesh* mesh) const +void Layer::computeGeometry(const sp& 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& 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 diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 8332a5af1..27e0c696f 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -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, @@ -150,7 +134,7 @@ public: uint32_t getTransactionFlags(uint32_t flags); uint32_t setTransactionFlags(uint32_t flags); - void computeGeometry(const sp& hw, LayerMesh* mesh) const; + void computeGeometry(const sp& hw, Mesh& mesh) const; Rect computeBounds() const; sp getHandle(); @@ -336,7 +320,7 @@ private: // drawing void clearWithOpenGL(const sp& 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& hw, const Region& clip) const; @@ -345,7 +329,7 @@ private: // constants sp mSurfaceFlingerConsumer; sp mBufferQueue; - GLuint mTextureName; + uint32_t mTextureName; bool mPremultipliedAlpha; String8 mName; mutable bool mDebug; diff --git a/services/surfaceflinger/LayerDim.cpp b/services/surfaceflinger/LayerDim.cpp index 062ad46a6..4e82babdb 100644 --- a/services/surfaceflinger/LayerDim.cpp +++ b/services/surfaceflinger/LayerDim.cpp @@ -43,11 +43,11 @@ void LayerDim::onDraw(const sp& 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(); } } diff --git a/services/surfaceflinger/RenderEngine/Description.cpp b/services/surfaceflinger/RenderEngine/Description.cpp new file mode 100644 index 000000000..9611b028f --- /dev/null +++ b/services/surfaceflinger/RenderEngine/Description.cpp @@ -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 +#include + +#include + +#include +#include + +#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 */ diff --git a/services/surfaceflinger/RenderEngine/Description.h b/services/surfaceflinger/RenderEngine/Description.h new file mode 100644 index 000000000..47b0d8e7d --- /dev/null +++ b/services/surfaceflinger/RenderEngine/Description.h @@ -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 + +#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_ */ diff --git a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp index 19499c9d6..27105a2f4 100644 --- a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp +++ b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp @@ -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); } } diff --git a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h index 15054bd2e..8bb7ed1c8 100644 --- a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h +++ b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h @@ -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; diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp new file mode 100644 index 000000000..6786065e4 --- /dev/null +++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp @@ -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 + +#include +#include + +#include + +#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 +// --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h new file mode 100644 index 000000000..873a6435f --- /dev/null +++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h @@ -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 +#include + +#include + +#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_ */ diff --git a/services/surfaceflinger/RenderEngine/Mesh.cpp b/services/surfaceflinger/RenderEngine/Mesh.cpp new file mode 100644 index 000000000..a08eea611 --- /dev/null +++ b/services/surfaceflinger/RenderEngine/Mesh.cpp @@ -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 */ diff --git a/services/surfaceflinger/RenderEngine/Mesh.h b/services/surfaceflinger/RenderEngine/Mesh.h new file mode 100644 index 000000000..599a15066 --- /dev/null +++ b/services/surfaceflinger/RenderEngine/Mesh.h @@ -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 + +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 */ diff --git a/services/surfaceflinger/RenderEngine/Program.cpp b/services/surfaceflinger/RenderEngine/Program.cpp new file mode 100644 index 000000000..586d1adeb --- /dev/null +++ b/services/surfaceflinger/RenderEngine/Program.cpp @@ -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 + +#include + +#include "Program.h" +#include "ProgramCache.h" +#include "Description.h" +#include + +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 */ diff --git a/services/surfaceflinger/RenderEngine/Program.h b/services/surfaceflinger/RenderEngine/Program.h new file mode 100644 index 000000000..91bb3dbbc --- /dev/null +++ b/services/surfaceflinger/RenderEngine/Program.h @@ -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 + +#include + +#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 */ diff --git a/services/surfaceflinger/RenderEngine/ProgramCache.cpp b/services/surfaceflinger/RenderEngine/ProgramCache.cpp new file mode 100644 index 000000000..835ed8a51 --- /dev/null +++ b/services/surfaceflinger/RenderEngine/ProgramCache.cpp @@ -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 +#include + +#include + +#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>> 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 */ diff --git a/services/surfaceflinger/RenderEngine/ProgramCache.h b/services/surfaceflinger/RenderEngine/ProgramCache.h new file mode 100644 index 000000000..fcbeffd30 --- /dev/null +++ b/services/surfaceflinger/RenderEngine/ProgramCache.h @@ -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 + +#include +#include +#include + +#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 { +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 mCache; +}; + + +ANDROID_BASIC_TYPES_TRAITS(ProgramCache::Key) + +} /* namespace android */ + +#endif /* SF_RENDER_ENGINE_PROGRAMCACHE_H */ diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.cpp b/services/surfaceflinger/RenderEngine/RenderEngine.cpp index cb77e389e..e8016ee34 100644 --- a/services/surfaceflinger/RenderEngine/RenderEngine.cpp +++ b/services/surfaceflinger/RenderEngine/RenderEngine.cpp @@ -15,11 +15,15 @@ */ #include +#include +#include #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 ; ileft; + 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 // --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.h b/services/surfaceflinger/RenderEngine/RenderEngine.h index e43bfa490..f4fa30b7f 100644 --- a/services/surfaceflinger/RenderEngine/RenderEngine.h +++ b/services/surfaceflinger/RenderEngine/RenderEngine.h @@ -22,12 +22,16 @@ #include #include +#include // --------------------------------------------------------------------------- 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; }; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index b76cde773..68b9950c8 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -23,8 +23,6 @@ #include #include -#include -#include #include #include @@ -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& hw, void SurfaceFlinger::doComposeSurfaces(const sp& 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& 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& 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& hw, const } // disable scissor at the end of the frame - glDisable(GL_SCISSOR_TEST); + engine.disableScissor(); } -void SurfaceFlinger::drawWormhole(const sp& 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& 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, @@ -1673,8 +1637,7 @@ void SurfaceFlinger::addClientLayer(const sp& client, mGraphicBufferProducerList.add(gbc->asBinder()); } -status_t SurfaceFlinger::removeLayer(const sp& layer) -{ +status_t SurfaceFlinger::removeLayer(const sp& 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) 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 diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 92fcc2590..ce096d318 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -21,7 +21,10 @@ #include #include -#include // needed for GLuint + +/* + * NOTE: Make sure this file doesn't include anything from or + */ #include @@ -91,12 +94,10 @@ public: }; // post an asynchronous message to the main thread - status_t postMessageAsync(const sp& msg, nsecs_t reltime = 0, - uint32_t flags = 0); + status_t postMessageAsync(const sp& msg, nsecs_t reltime = 0, uint32_t flags = 0); // post a synchronous message to the main thread - status_t postMessageSync(const sp& msg, nsecs_t reltime = 0, - uint32_t flags = 0); + status_t postMessageSync(const sp& 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, - const layer_state_t& s); + uint32_t setClientStateLocked(const sp& 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& hw, - const Region& dirtyRegion); - void doComposeSurfaces(const sp& hw, - const Region& dirty); + void doDisplayComposition(const sp& hw, const Region& dirtyRegion); + void doComposeSurfaces(const sp& hw, const Region& dirty); void postFramebuffer(); - void drawWormhole(const sp& hw, - const Region& region) const; + void drawWormhole(const sp& hw, const Region& region) const; /* ------------------------------------------------------------------------ * Display management @@ -382,14 +379,10 @@ private: /* ------------------------------------------------------------------------ * Debugging & dumpsys */ - void listLayersLocked(const Vector& args, size_t& index, - String8& result) const; - void dumpStatsLocked(const Vector& args, size_t& index, - String8& result) const; - void clearStatsLocked(const Vector& args, size_t& index, - String8& result); - void dumpAllLocked(const Vector& args, size_t& index, - String8& result) const; + void listLayersLocked(const Vector& args, size_t& index, String8& result) const; + void dumpStatsLocked(const Vector& args, size_t& index, String8& result) const; + void clearStatsLocked(const Vector& args, size_t& index, String8& result); + void dumpAllLocked(const Vector& args, size_t& index, String8& result) const; bool startDdmConnection(); static void appendSfConfigString(String8& result); void checkScreenshot(const sp& buf, void const* vaddr, diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.cpp b/services/surfaceflinger/SurfaceFlingerConsumer.cpp index e95e057bf..552372b14 100644 --- a/services/surfaceflinger/SurfaceFlingerConsumer.cpp +++ b/services/surfaceflinger/SurfaceFlingerConsumer.cpp @@ -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 diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.h b/services/surfaceflinger/SurfaceFlingerConsumer.h index aa2b37fae..c7fc1641d 100644 --- a/services/surfaceflinger/SurfaceFlingerConsumer.h +++ b/services/surfaceflinger/SurfaceFlingerConsumer.h @@ -27,10 +27,8 @@ namespace android { */ class SurfaceFlingerConsumer : public GLConsumer { public: - SurfaceFlingerConsumer(const sp& bq, GLuint tex, - GLenum texTarget = GL_TEXTURE_EXTERNAL_OES, - bool useFenceSync = true) - : GLConsumer(bq, tex, texTarget, useFenceSync) + SurfaceFlingerConsumer(const sp& bq, uint32_t tex) + : GLConsumer(bq, tex, GLConsumer::TEXTURE_EXTERNAL, false) {} class BufferRejecter {