OSDN Git Service

auto determine the density if not provided in surfaceflinger
[android-x86/frameworks-native.git] / services / surfaceflinger / SurfaceFlinger.cpp
index 7e048f3..385e39e 100644 (file)
@@ -560,8 +560,27 @@ status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display,
     public:
         static int getEmuDensity() {
             return getDensityFromProperty("qemu.sf.lcd_density"); }
-        static int getBuildDensity()  {
-            return getDensityFromProperty("ro.sf.lcd_density"); }
+        static int getBuildDensity(const DisplayInfo& info)  {
+            static int density = getDensityFromProperty("ro.sf.lcd_density");
+#if defined(__i386__) || defined(__x86_64__)
+            if (density == 0) {
+                uint32_t area = info.w * info.h;
+                if (area <= 800 * 480) {
+                    density = 120;
+                } else if (area <= 1024 * 600) {
+                    density = 130;
+                } else if (area < 1024 * 768) {
+                    density = 140;
+                } else if (area < 1920 * 1080) {
+                    density = 160;
+                } else {
+                    density = 240;
+                }
+                ALOGI("auto set density to %d", density);
+            }
+#endif
+            return density;
+        }
     };
 
     configs->clear();
@@ -571,10 +590,12 @@ status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display,
 
         float xdpi = hwConfig->getDpiX();
         float ydpi = hwConfig->getDpiY();
+        info.w = hwConfig->getWidth();
+        info.h = hwConfig->getHeight();
 
         if (type == DisplayDevice::DISPLAY_PRIMARY) {
             // The density of the device is provided by a build property
-            float density = Density::getBuildDensity() / 160.0f;
+            float density = Density::getBuildDensity(info) / 160.0f;
             if (density == 0) {
                 // the build doesn't provide a density -- this is wrong!
                 // use xdpi instead
@@ -598,8 +619,6 @@ status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display,
             info.orientation = 0;
         }
 
-        info.w = hwConfig->getWidth();
-        info.h = hwConfig->getHeight();
         info.xdpi = xdpi;
         info.ydpi = ydpi;
         info.fps = 1e9 / hwConfig->getVsyncPeriod();
@@ -752,6 +771,20 @@ void SurfaceFlinger::waitForEvent() {
     mEventQueue.waitMessage();
 }
 
+#ifdef CONSOLE_MANAGER
+void SurfaceFlinger::screenReleased(const sp<IBinder>& display) {
+    // this may be called by a signal handler, we can't do too much in here
+    setPowerMode(display, HWC_POWER_MODE_OFF);
+    signalLayerUpdate();
+}
+
+void SurfaceFlinger::screenAcquired(const sp<IBinder>& display) {
+    // this may be called by a signal handler, we can't do too much in here
+    setPowerMode(display, HWC_POWER_MODE_NORMAL);
+    signalLayerUpdate();
+}
+#endif
+
 void SurfaceFlinger::signalTransaction() {
     mEventQueue.invalidate();
 }
@@ -1473,10 +1506,19 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
                                     NATIVE_WINDOW_HEIGHT, &height);
                             ALOGE_IF(status != NO_ERROR,
                                     "Unable to query height (%d)", status);
+                            int intFormat = 0;
+                            status = state.surface->query(
+                                    NATIVE_WINDOW_FORMAT, &intFormat);
+                            ALOGE_IF(status != NO_ERROR,
+                                    "Unable to query format (%d)", status);
+                            auto format = static_cast<android_pixel_format_t>(
+                                    intFormat);
 
-                            mHwc->allocateVirtualDisplay(width, height,
+                            mHwc->allocateVirtualDisplay(width, height, &format,
                                     &hwcId);
 
+                            // TODO: Plumb requested format back up to consumer
+
                             sp<VirtualDisplaySurface> vds =
                                     new VirtualDisplaySurface(*mHwc,
                                             hwcId, state.surface, bqProducer,
@@ -2152,6 +2194,13 @@ void SurfaceFlinger::setTransactionState(
         }
     }
 
+    // If a synchronous transaction is explicitly requested without any changes,
+    // force a transaction anyway. This can be used as a flush mechanism for
+    // previous async transactions.
+    if (transactionFlags == 0 && (flags & eSynchronous)) {
+        transactionFlags = eTransactionNeeded;
+    }
+
     if (transactionFlags) {
         // this triggers the transaction
         setTransactionFlags(transactionFlags);
@@ -2235,9 +2284,12 @@ uint32_t SurfaceFlinger::setClientStateLocked(
     sp<Layer> layer(client->getLayerUser(s.surface));
     if (layer != 0) {
         const uint32_t what = s.what;
+        bool positionAppliesWithResize =
+                what & layer_state_t::ePositionAppliesWithResize;
         if (what & layer_state_t::ePositionChanged) {
-            if (layer->setPosition(s.x, s.y))
+            if (layer->setPosition(s.x, s.y, !positionAppliesWithResize)) {
                 flags |= eTraversalNeeded;
+            }
         }
         if (what & layer_state_t::eLayerChanged) {
             // NOTE: index needs to be calculated before we update the state