OSDN Git Service

rework a bit how we scissor the display
authorMathias Agopian <mathias@google.com>
Wed, 31 Oct 2012 01:08:06 +0000 (18:08 -0700)
committerMathias Agopian <mathias@google.com>
Wed, 31 Oct 2012 21:22:51 +0000 (14:22 -0700)
the scissor rect is now computed once by DisplayDevice
and is combined with the "undefined" region so that
the letter-boxed area of the screen get cleared in
drawWormhole.

Bug: 7149437
Change-Id: Id2f30516a5786f32eace7f876ff32028f954f357

services/surfaceflinger/DisplayDevice.cpp
services/surfaceflinger/DisplayDevice.h
services/surfaceflinger/SurfaceFlinger.cpp

index ce98b67..8cf527a 100644 (file)
@@ -426,6 +426,11 @@ void DisplayDevice::updateGeometryTransform() {
         const uint8_t type = mGlobalTransform.getType();
         mNeedsFiltering = (!mGlobalTransform.preserveRects() ||
                 (type >= Transform::SCALE));
+
+        mScissor = mGlobalTransform.transform(mViewport);
+        if (mScissor.isEmpty()) {
+            mScissor.set(getBounds());
+        }
     }
 }
 
@@ -435,7 +440,7 @@ void DisplayDevice::dump(String8& result, char* buffer, size_t SIZE) const {
         "+ DisplayDevice: %s\n"
         "   type=%x, layerStack=%u, (%4dx%4d), ANativeWindow=%p, orient=%2d (type=%08x), "
         "flips=%u, isSecure=%d, secureVis=%d, acquired=%d, numLayers=%u\n"
-        "   v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], "
+        "   v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d],"
         "transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n",
         mDisplayName.string(), mType,
         mLayerStack, mDisplayWidth, mDisplayHeight, mNativeWindow.get(),
@@ -443,6 +448,7 @@ void DisplayDevice::dump(String8& result, char* buffer, size_t SIZE) const {
         mIsSecure, mSecureLayerVisible, mScreenAcquired, mVisibleLayersSortedByZ.size(),
         mViewport.left, mViewport.top, mViewport.right, mViewport.bottom,
         mFrame.left, mFrame.top, mFrame.right, mFrame.bottom,
+        mScissor.left, mScissor.top, mScissor.right, mScissor.bottom,
         tr[0][0], tr[1][0], tr[2][0],
         tr[0][1], tr[1][1], tr[2][1],
         tr[0][2], tr[1][2], tr[2][2]);
index d6da422..bb6eb70 100644 (file)
@@ -107,6 +107,7 @@ public:
     const Transform&        getTransform() const { return mGlobalTransform; }
     const Rect&             getViewport() const { return mViewport; }
     const Rect&             getFrame() const { return mFrame; }
+    const Rect&             getScissor() const { return mScissor; }
     bool                    needsFiltering() const { return mNeedsFiltering; }
 
     uint32_t                getLayerStack() const { return mLayerStack; }
@@ -200,8 +201,12 @@ private:
 
     uint32_t mLayerStack;
     int mOrientation;
+    // user-provided visible area of the layer stack
     Rect mViewport;
+    // user-provided rectangle where mViewport gets mapped to
     Rect mFrame;
+    // pre-computed scissor to apply to the display
+    Rect mScissor;
     Transform mGlobalTransform;
     bool mNeedsFiltering;
 };
index 7ee6e5e..9574295 100644 (file)
@@ -1493,7 +1493,20 @@ void SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const
             glClearColor(0, 0, 0, 0);
             glClear(GL_COLOR_BUFFER_BIT);
         } else {
-            const Region region(hw->undefinedRegion.intersect(dirty));
+            // we start with the whole screen area
+            const Region bounds(hw->getBounds());
+
+            // we remove the scissor part
+            // we're left with the letterbox region
+            // (common case is that letterbox ends-up being empty)
+            const Region letterbox(bounds.subtract(hw->getScissor()));
+
+            // compute the area to clear
+            Region region(hw->undefinedRegion.merge(letterbox));
+
+            // but limit it to the dirty region
+            region.andSelf(dirty);
+
             // screen is already cleared here
             if (!region.isEmpty()) {
                 // can happen with SurfaceView
@@ -1501,13 +1514,12 @@ void SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const
             }
         }
 
-        if (hw->getDisplayType() >= DisplayDevice::DISPLAY_EXTERNAL) {
-            // TODO: just to be on the safe side, we don't set the
+        if (hw->getDisplayType() != DisplayDevice::DISPLAY_PRIMARY) {
+            // just to be on the safe side, we don't set the
             // scissor on the main display. It should never be needed
             // anyways (though in theory it could since the API allows it).
             const Rect& bounds(hw->getBounds());
-            const Transform& tr(hw->getTransform());
-            const Rect scissor(tr.transform(hw->getViewport()));
+            const Rect& scissor(hw->getScissor());
             if (scissor != bounds) {
                 // scissor doesn't match the screen's dimensions, so we
                 // need to clear everything outside of it and enable
@@ -1515,9 +1527,6 @@ void SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const
                 const GLint height = hw->getHeight();
                 glScissor(scissor.left, height - scissor.bottom,
                         scissor.getWidth(), scissor.getHeight());
-                // clear everything unscissored
-                glClearColor(0, 0, 0, 0);
-                glClear(GL_COLOR_BUFFER_BIT);
                 // enable scissor for this frame
                 glEnable(GL_SCISSOR_TEST);
             }