OSDN Git Service

Merge "Bug fixes for SensorService" into klp-dev
[android-x86/frameworks-native.git] / services / surfaceflinger / Layer.cpp
index 2defe34..61af51f 100644 (file)
@@ -74,13 +74,15 @@ Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
         mFrameLatencyNeeded(false),
         mFiltering(false),
         mNeedsFiltering(false),
+        mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
         mSecure(false),
         mProtectedByApp(false),
         mHasSurface(false),
         mClientRef(client)
 {
     mCurrentCrop.makeInvalid();
-    glGenTextures(1, &mTextureName);
+    mFlinger->getRenderEngine().genTextures(1, &mTextureName);
+    mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
 
     uint32_t layerFlags = 0;
     if (flags & ISurfaceComposerClient::eHidden)
@@ -110,13 +112,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);
@@ -288,7 +287,13 @@ FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
     // pixels in the buffer.
     // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
     // a viewport clipping and a window transform. we should use floating point to fix this.
-    Rect activeCrop(s.transform.transform(s.active.crop));
+
+    Rect activeCrop(s.active.w, s.active.h);
+    if (!s.active.crop.isEmpty()) {
+        activeCrop = s.active.crop;
+    }
+
+    activeCrop = s.transform.transform(activeCrop);
     activeCrop.intersect(hw->getViewport(), &activeCrop);
     activeCrop = s.transform.inverse().transform(activeCrop);
 
@@ -371,7 +376,21 @@ void Layer::setGeometry(
      */
 
     const Transform bufferOrientation(mCurrentTransform);
-    const Transform transform(tr * s.transform * bufferOrientation);
+    Transform transform(tr * s.transform * bufferOrientation);
+
+    if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
+        /*
+         * the code below applies the display's inverse transform to the buffer
+         */
+        uint32_t invTransform = hw->getOrientationTransform();
+        // calculate the inverse transform
+        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
+            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
+                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
+        }
+        // and apply to the current transform
+        transform = transform * Transform(invTransform);
+    }
 
     // this gives us only the "orientation" component of the transform
     const uint32_t orientation = transform.getOrientation();
@@ -484,8 +503,40 @@ void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
         mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
         mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
 
+        if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
+
+            /*
+             * the code below applies the display's inverse transform to the texture transform
+             */
+
+            // create a 4x4 transform matrix from the display transform flags
+            const mat4 flipH(-1,0,0,0,  0,1,0,0, 0,0,1,0, 1,0,0,1);
+            const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
+            const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
+
+            mat4 tr;
+            uint32_t transform = hw->getOrientationTransform();
+            if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
+                tr = tr * rot90;
+            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
+                tr = tr * flipH;
+            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
+                tr = tr * flipV;
+
+            // calculate the inverse
+            tr = inverse(tr);
+
+            // and finally apply it to the original texture matrix
+            const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
+            memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
+        }
+
         // Set things up for texturing.
-        engine.setupLayerTexturing(mTextureName, useFiltering, textureMatrix);
+        mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
+        mTexture.setFiltering(useFiltering);
+        mTexture.setMatrix(textureMatrix);
+
+        engine.setupLayerTexturing(mTexture);
     } else {
         engine.setupLayerBlackedOut();
     }
@@ -495,14 +546,12 @@ 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);
+    RenderEngine& engine(mFlinger->getRenderEngine());
+    computeGeometry(hw, mMesh);
+    engine.setupFillWithColor(red, green, blue, alpha);
+    engine.drawMesh(mMesh);
 }
 
 void Layer::clearWithOpenGL(
@@ -515,8 +564,7 @@ void Layer::drawWithOpenGL(
     const uint32_t fbHeight = hw->getHeight();
     const State& s(getDrawingState());
 
-    LayerMesh mesh;
-    computeGeometry(hw, &mesh);
+    computeGeometry(hw, mMesh);
 
     /*
      * NOTE: the way we compute the texture coordinates here produces
@@ -527,36 +575,29 @@ void Layer::drawWithOpenGL(
      *
      * The GL code below is more logical (imho), and the difference with
      * HWC is due to a limitation of the HWC API to integers -- a question
-     * is suspend is wether we should ignore this problem or revert to
+     * is suspend is whether we should ignore this problem or revert to
      * GL composition when a buffer scaling is applied (maybe with some
      * minimal value)? Or, we could make GL behave like HWC -- but this feel
      * like more of a hack.
      */
     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];
-    }
+    Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
+    texCoords[0] = vec2(left, 1.0f - top);
+    texCoords[1] = vec2(left, 1.0f - bottom);
+    texCoords[2] = vec2(right, 1.0f - bottom);
+    texCoords[3] = vec2(right, 1.0f - top);
 
     RenderEngine& engine(mFlinger->getRenderEngine());
     engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(), s.alpha);
-    engine.drawMesh2D(mesh.getVertices(), texCoords, mesh.getVertexCount());
+    engine.drawMesh(mMesh);
     engine.disableBlending();
 }
 
@@ -582,6 +623,7 @@ bool Layer::getOpacityForFormat(uint32_t format) {
     switch (format) {
         case HAL_PIXEL_FORMAT_RGBA_8888:
         case HAL_PIXEL_FORMAT_BGRA_8888:
+        case HAL_PIXEL_FORMAT_sRGB_A_8888:
             return false;
     }
     // in all other case, we have no blending (also for unknown formats)
@@ -592,7 +634,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 +645,14 @@ 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];
-        }
+
+    Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
+    position[0] = tr.transform(win.left,  win.top);
+    position[1] = tr.transform(win.left,  win.bottom);
+    position[2] = tr.transform(win.right, win.bottom);
+    position[3] = tr.transform(win.right, win.top);
+    for (size_t i=0 ; i<4 ; i++) {
+        position[i].y = hw_h - position[i].y;
     }
 }
 
@@ -989,6 +1031,8 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions)
                     if (front.active.w != bufWidth ||
                         front.active.h != bufHeight) {
                         // reject this buffer
+                        //ALOGD("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
+                        //        bufWidth, bufHeight, front.active.w, front.active.h);
                         return true;
                     }
                 }
@@ -1195,6 +1239,12 @@ Layer::LayerCleaner::~LayerCleaner() {
 }
 
 // ---------------------------------------------------------------------------
+}; // namespace android
 
+#if defined(__gl_h_)
+#error "don't include gl/gl.h in this file"
+#endif
 
-}; // namespace android
+#if defined(__gl2_h_)
+#error "don't include gl2/gl2.h in this file"
+#endif