summaryrefslogtreecommitdiffstats
path: root/services/surfaceflinger
diff options
context:
space:
mode:
Diffstat (limited to 'services/surfaceflinger')
-rw-r--r--services/surfaceflinger/Android.mk15
-rw-r--r--services/surfaceflinger/DispSync.cpp2
-rw-r--r--services/surfaceflinger/DispSync.h7
-rw-r--r--services/surfaceflinger/DisplayDevice.cpp11
-rw-r--r--services/surfaceflinger/DisplayDevice.h8
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.cpp43
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.h19
-rw-r--r--services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp8
-rw-r--r--services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h5
-rw-r--r--services/surfaceflinger/DisplayUtils.cpp173
-rw-r--r--services/surfaceflinger/DisplayUtils.h78
-rw-r--r--services/surfaceflinger/EventThread.cpp2
-rw-r--r--services/surfaceflinger/Layer.cpp6
-rw-r--r--services/surfaceflinger/Layer.h21
-rw-r--r--services/surfaceflinger/LayerDim.cpp9
-rw-r--r--services/surfaceflinger/LayerDim.h2
-rw-r--r--services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp63
-rw-r--r--services/surfaceflinger/RenderEngine/GLES11RenderEngine.h5
-rw-r--r--services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp41
-rw-r--r--services/surfaceflinger/RenderEngine/GLES20RenderEngine.h5
-rw-r--r--services/surfaceflinger/RenderEngine/RenderEngine.cpp9
-rw-r--r--services/surfaceflinger/RenderEngine/RenderEngine.h11
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp149
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h50
-rw-r--r--services/surfaceflinger/main_surfaceflinger.cpp3
25 files changed, 660 insertions, 85 deletions
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 1eb2361..276a242 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -34,8 +34,8 @@ LOCAL_SRC_FILES := \
RenderEngine/Texture.cpp \
RenderEngine/GLES10RenderEngine.cpp \
RenderEngine/GLES11RenderEngine.cpp \
- RenderEngine/GLES20RenderEngine.cpp
-
+ RenderEngine/GLES20RenderEngine.cpp \
+ DisplayUtils.cpp
LOCAL_CFLAGS := -DLOG_TAG=\"SurfaceFlinger\"
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
@@ -106,6 +106,17 @@ LOCAL_SHARED_LIBRARIES := \
libgui \
libpowermanager
+
+ifeq ($(TARGET_USES_QCOM_BSP), true)
+ LOCAL_WHOLE_STATIC_LIBRARIES += libexsurfaceflinger
+ LOCAL_C_INCLUDES += vendor/qcom/opensource/display-frameworks/native/services/surfaceflinger
+ LOCAL_C_INCLUDES += vendor/qcom/opensource/display-frameworks/include
+ LOCAL_C_INCLUDES += $(call project-path-for,qcom-display)/libgralloc
+ LOCAL_C_INCLUDES += $(call project-path-for,qcom-display)/libqdutils
+ LOCAL_SHARED_LIBRARIES += libqdutils
+ LOCAL_CFLAGS += -DQTI_BSP
+endif
+
LOCAL_MODULE := libsurfaceflinger
LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
diff --git a/services/surfaceflinger/DispSync.cpp b/services/surfaceflinger/DispSync.cpp
index 3738a55..73b3897 100644
--- a/services/surfaceflinger/DispSync.cpp
+++ b/services/surfaceflinger/DispSync.cpp
@@ -21,6 +21,7 @@
#include <math.h>
+#include <cutils/iosched_policy.h>
#include <cutils/log.h>
#include <ui/Fence.h>
@@ -292,6 +293,7 @@ DispSync::DispSync() :
mThread(new DispSyncThread()) {
mThread->run("DispSync", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
+ android_set_rt_ioprio(mThread->getTid(), 1);
reset();
beginResync();
diff --git a/services/surfaceflinger/DispSync.h b/services/surfaceflinger/DispSync.h
index 67142b6..ebe19a5 100644
--- a/services/surfaceflinger/DispSync.h
+++ b/services/surfaceflinger/DispSync.h
@@ -26,11 +26,8 @@
namespace android {
// Ignore present (retire) fences if the device doesn't have support for the
-// sync framework, or if all phase offsets are zero. The latter is useful
-// because it allows us to avoid resync bursts on devices that don't need
-// phase-offset VSYNC events.
-#if defined(RUNNING_WITHOUT_SYNC_FRAMEWORK) || \
- (VSYNC_EVENT_PHASE_OFFSET_NS == 0 && SF_VSYNC_EVENT_PHASE_OFFSET_NS == 0)
+// sync framework.
+#if defined(RUNNING_WITHOUT_SYNC_FRAMEWORK)
static const bool kIgnorePresentFences = true;
#else
static const bool kIgnorePresentFences = false;
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 13d44f3..baff5ba 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -90,6 +90,7 @@ DisplayDevice::DisplayDevice(
{
mNativeWindow = new Surface(producer, false);
ANativeWindow* const window = mNativeWindow.get();
+ char property[PROPERTY_VALUE_MAX];
/*
* Create our display's surface
@@ -140,6 +141,11 @@ DisplayDevice::DisplayDevice(
break;
}
+ mPanelInverseMounted = false;
+ // Check if panel is inverse mounted (contents show up HV flipped)
+ property_get("persist.panel.inversemounted", property, "0");
+ mPanelInverseMounted = !!atoi(property);
+
// initialize the display orientation transform.
setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);
}
@@ -402,6 +408,11 @@ status_t DisplayDevice::orientationToTransfrom(
default:
return BAD_VALUE;
}
+
+ if (DISPLAY_PRIMARY == mHwcDisplayId && isPanelInverseMounted()) {
+ flags = flags ^ Transform::ROT_180;
+ }
+
tr->set(flags, w, h);
return NO_ERROR;
}
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 8695a44..f492a42 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -126,6 +126,10 @@ public:
int32_t getHwcDisplayId() const { return mHwcDisplayId; }
const wp<IBinder>& getDisplayToken() const { return mDisplayToken; }
+ bool isPanelInverseMounted() const {
+ return mPanelInverseMounted;
+ }
+
// We pass in mustRecompose so we can keep VirtualDisplaySurface's state
// machine happy without actually queueing a buffer if nothing has changed
status_t beginFrame(bool mustRecompose) const;
@@ -209,7 +213,7 @@ private:
/*
* Transaction state
*/
- static status_t orientationToTransfrom(int orientation,
+ status_t orientationToTransfrom(int orientation,
int w, int h, Transform* tr);
uint32_t mLayerStack;
@@ -226,6 +230,8 @@ private:
int mPowerMode;
// Current active config
int mActiveConfig;
+ // Panel is inverse mounted
+ int mPanelInverseMounted;
};
}; // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 0859149..c57dd5f 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -190,6 +190,11 @@ HWComposer::HWComposer(
// we don't have VSYNC support, we need to fake it
mVSyncThread = new VSyncThread(*this);
}
+
+ mDimComp = 0;
+ if (mHwc) {
+ mHwc->query(mHwc, HWC_BACKGROUND_LAYER_SUPPORTED, &mDimComp);
+ }
}
HWComposer::~HWComposer() {
@@ -368,7 +373,12 @@ status_t HWComposer::queryDisplayProperties(int disp) {
return err;
}
- mDisplayData[disp].currentConfig = 0;
+ int currentConfig = getActiveConfig(disp);
+ if (currentConfig < 0 || currentConfig > static_cast<int>((numConfigs-1))) {
+ ALOGE("%s: Invalid display config! %d", __FUNCTION__, currentConfig);
+ currentConfig = 0;
+ }
+ mDisplayData[disp].currentConfig = currentConfig;
for (size_t c = 0; c < numConfigs; ++c) {
err = mHwc->getDisplayAttributes(mHwc, disp, configs[c],
DISPLAY_ATTRIBUTES, values);
@@ -716,6 +726,9 @@ status_t HWComposer::prepare() {
if (l.compositionType == HWC_OVERLAY) {
disp.hasOvComp = true;
}
+ if (isCompositionTypeBlit(l.compositionType)) {
+ disp.hasFbComp = true;
+ }
if (l.compositionType == HWC_CURSOR_OVERLAY) {
disp.hasOvComp = true;
}
@@ -816,15 +829,31 @@ status_t HWComposer::setPowerMode(int disp, int mode) {
status_t HWComposer::setActiveConfig(int disp, int mode) {
LOG_FATAL_IF(disp >= VIRTUAL_DISPLAY_ID_BASE);
DisplayData& dd(mDisplayData[disp]);
- dd.currentConfig = mode;
if (mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_4)) {
- return (status_t)mHwc->setActiveConfig(mHwc, disp, mode);
+ status_t status = static_cast<status_t>(
+ mHwc->setActiveConfig(mHwc, disp, mode));
+ if (status == NO_ERROR) {
+ dd.currentConfig = mode;
+ } else {
+ ALOGE("%s Failed to set new config (%d) for display (%d)",
+ __FUNCTION__, mode, disp);
+ }
+ return status;
} else {
LOG_FATAL_IF(mode != 0);
}
return NO_ERROR;
}
+int HWComposer::getActiveConfig(int disp) const {
+ LOG_FATAL_IF(disp >= VIRTUAL_DISPLAY_ID_BASE);
+ if (mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_4)) {
+ return mHwc->getActiveConfig(mHwc, disp);
+ } else {
+ return 0;
+ }
+}
+
void HWComposer::disconnectDisplay(int disp) {
LOG_ALWAYS_FATAL_IF(disp < 0 || disp == HWC_DISPLAY_PRIMARY);
DisplayData& dd(mDisplayData[disp]);
@@ -998,6 +1027,10 @@ public:
getLayer()->flags &= ~HWC_SKIP_LAYER;
}
}
+ virtual void setDim() {
+ setSkip(false);
+ getLayer()->flags |= 0x80000000;
+ }
virtual void setIsCursorLayerHint(bool isCursor) {
if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_4)) {
if (isCursor) {
@@ -1233,7 +1266,7 @@ void HWComposer::dump(String8& result) const {
if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_3)) {
result.appendFormat(
" %9s | %08" PRIxPTR " | %04x | %04x | %02x | %04x | %-11s |%7.1f,%7.1f,%7.1f,%7.1f |%5d,%5d,%5d,%5d | %s\n",
- compositionTypeName[type],
+ (isCompositionTypeBlit(l.compositionType)) ? "HWC_BLIT" : compositionTypeName[type],
intptr_t(l.handle), l.hints, l.flags, l.transform, l.blending, formatStr.string(),
l.sourceCropf.left, l.sourceCropf.top, l.sourceCropf.right, l.sourceCropf.bottom,
l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom,
@@ -1241,7 +1274,7 @@ void HWComposer::dump(String8& result) const {
} else {
result.appendFormat(
" %9s | %08" PRIxPTR " | %04x | %04x | %02x | %04x | %-11s |%7d,%7d,%7d,%7d |%5d,%5d,%5d,%5d | %s\n",
- compositionTypeName[type],
+ (isCompositionTypeBlit(l.compositionType)) ? "HWC_BLIT" : compositionTypeName[type],
intptr_t(l.handle), l.hints, l.flags, l.transform, l.blending, formatStr.string(),
l.sourceCrop.left, l.sourceCrop.top, l.sourceCrop.right, l.sourceCrop.bottom,
l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom,
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 5e0b3d8..862288f 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -74,7 +74,7 @@ public:
const sp<SurfaceFlinger>& flinger,
EventHandler& handler);
- ~HWComposer();
+ virtual ~HWComposer();
status_t initCheck() const;
@@ -103,6 +103,9 @@ public:
// set active config
status_t setActiveConfig(int disp, int mode);
+ // get active config
+ int getActiveConfig(int disp) const;
+
// reset state when an external, non-virtual display is disconnected
void disconnectDisplay(int disp);
@@ -117,6 +120,9 @@ public:
// does this display have layers handled by GLES
bool hasGlesComposition(int32_t id) const;
+ // does this display support dim layer composition
+ bool hasDimComposition() const { return (mDimComp == 1); }
+
// get the releaseFence file descriptor for a display's framebuffer layer.
// the release fence is only valid after commit()
sp<Fence> getAndResetReleaseFence(int32_t id);
@@ -162,6 +168,7 @@ public:
virtual sp<Fence> getAndResetReleaseFence() = 0;
virtual void setDefaultState() = 0;
virtual void setSkip(bool skip) = 0;
+ virtual void setDim() = 0;
virtual void setIsCursorLayerHint(bool isCursor = true) = 0;
virtual void setBlending(uint32_t blending) = 0;
virtual void setTransform(uint32_t transform) = 0;
@@ -302,6 +309,14 @@ public:
// for debugging ----------------------------------------------------------
void dump(String8& out) const;
+ /* ------------------------------------------------------------------------
+ * Extensions
+ */
+ virtual inline bool isVDSEnabled() const { return true; };
+ virtual inline bool isCompositionTypeBlit(const int32_t /*compType*/) const {
+ return false;
+ };
+
private:
void loadHwcModule();
int loadFbHalModule();
@@ -372,6 +387,8 @@ private:
// thread-safe
mutable Mutex mEventControlLock;
+
+ int mDimComp;
};
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
index ba4c198..1e4f907 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -152,7 +152,7 @@ status_t VirtualDisplaySurface::prepareFrame(CompositionType compositionType) {
// format/usage and get a new buffer when the GLES driver calls
// dequeueBuffer().
mOutputFormat = mDefaultOutputFormat;
- mOutputUsage = GRALLOC_USAGE_HW_COMPOSER;
+ setOutputUsage(GRALLOC_USAGE_HW_COMPOSER);
refreshOutputBuffer();
}
@@ -377,7 +377,7 @@ status_t VirtualDisplaySurface::dequeueBuffer(int* pslot, sp<Fence>* fence, bool
mSinkBufferWidth, mSinkBufferHeight,
buf->getPixelFormat(), buf->getUsage());
mOutputFormat = format;
- mOutputUsage = usage;
+ setOutputUsage(usage);
result = refreshOutputBuffer();
if (result < 0)
return result;
@@ -616,6 +616,10 @@ const char* VirtualDisplaySurface::dbgSourceStr(Source s) {
}
}
+void VirtualDisplaySurface::setOutputUsage(uint32_t usage) {
+ mOutputUsage = usage;
+}
+
// ---------------------------------------------------------------------------
} // namespace android
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
index 6298751..3d0e412 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
@@ -72,6 +72,10 @@ class VirtualDisplaySurface : public DisplaySurface,
public BnGraphicBufferProducer,
private ConsumerBase {
public:
+#ifdef QTI_BSP
+ friend class ExVirtualDisplaySurface;
+#endif
+
VirtualDisplaySurface(HWComposer& hwc, int32_t dispId,
const sp<IGraphicBufferProducer>& sink,
const sp<IGraphicBufferProducer>& bqProducer,
@@ -118,6 +122,7 @@ private:
virtual status_t allowAllocation(bool allow);
virtual status_t setGenerationNumber(uint32_t generationNumber);
virtual String8 getConsumerName() const override;
+ virtual void setOutputUsage(uint32_t flag);
//
// Utility methods
diff --git a/services/surfaceflinger/DisplayUtils.cpp b/services/surfaceflinger/DisplayUtils.cpp
new file mode 100644
index 0000000..1f4c21c
--- /dev/null
+++ b/services/surfaceflinger/DisplayUtils.cpp
@@ -0,0 +1,173 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+
+#include <gui/Surface.h>
+#include <ui/GraphicBuffer.h>
+
+#include "RenderEngine/RenderEngine.h"
+#include "DisplayHardware/FramebufferSurface.h"
+#include "DisplayUtils.h"
+#ifdef QTI_BSP
+#include <ExSurfaceFlinger.h>
+#include <ExLayer.h>
+#include <DisplayHardware/ExHWComposer.h>
+#include <DisplayHardware/ExVirtualDisplaySurface.h>
+#endif
+#include <dlfcn.h>
+#include <cutils/properties.h>
+
+namespace android {
+
+DisplayUtils* DisplayUtils::sDisplayUtils = NULL;
+bool DisplayUtils::sUseExtendedImpls = false;
+
+DisplayUtils::DisplayUtils() {
+#ifdef QTI_BSP
+ sUseExtendedImpls = true;
+#endif
+}
+
+DisplayUtils* DisplayUtils::getInstance() {
+ if(sDisplayUtils == NULL) {
+ sDisplayUtils = new DisplayUtils();
+ }
+ return sDisplayUtils;
+}
+
+SurfaceFlinger* DisplayUtils::getSFInstance() {
+#ifdef QTI_BSP
+ if(sUseExtendedImpls) {
+ return new ExSurfaceFlinger();
+ }
+#endif
+ return new SurfaceFlinger();
+}
+
+Layer* DisplayUtils::getLayerInstance(SurfaceFlinger* flinger,
+ const sp<Client>& client, const String8& name,
+ uint32_t w, uint32_t h, uint32_t flags) {
+#ifdef QTI_BSP
+ if(sUseExtendedImpls) {
+ return new ExLayer(flinger, client, name, w, h, flags);
+ }
+#endif
+ return new Layer(flinger, client, name, w, h, flags);
+}
+
+HWComposer* DisplayUtils::getHWCInstance(
+ const sp<SurfaceFlinger>& flinger,
+ HWComposer::EventHandler& handler) {
+#ifdef QTI_BSP
+ if(sUseExtendedImpls) {
+ return new ExHWComposer(flinger, handler);
+ }
+#endif
+ return new HWComposer(flinger,handler);
+}
+
+void DisplayUtils::initVDSInstance(HWComposer* hwc, int32_t hwcDisplayId,
+ sp<IGraphicBufferProducer> currentStateSurface, sp<DisplaySurface> &dispSurface,
+ sp<IGraphicBufferProducer> &producer, sp<IGraphicBufferProducer> bqProducer,
+ sp<IGraphicBufferConsumer> bqConsumer, String8 currentStateDisplayName,
+ bool currentStateIsSecure, int currentStateType)
+{
+#ifdef QTI_BSP
+ if(sUseExtendedImpls) {
+ if(hwc->isVDSEnabled()) {
+ VirtualDisplaySurface* vds = new ExVirtualDisplaySurface(*hwc, hwcDisplayId,
+ currentStateSurface, bqProducer, bqConsumer, currentStateDisplayName,
+ currentStateIsSecure);
+ dispSurface = vds;
+ producer = vds;
+ } else if(!createV4L2BasedVirtualDisplay(hwc, hwcDisplayId, dispSurface, producer,
+ currentStateSurface, bqProducer, bqConsumer, currentStateType)) {
+ VirtualDisplaySurface* vds = new VirtualDisplaySurface(*hwc, hwcDisplayId,
+ currentStateSurface, bqProducer, bqConsumer, currentStateDisplayName);
+ dispSurface = vds;
+ producer = vds;
+ }
+ } else {
+#endif
+ (void)currentStateIsSecure;
+ (void)currentStateType;
+ VirtualDisplaySurface* vds = new VirtualDisplaySurface(*hwc, hwcDisplayId,
+ currentStateSurface, bqProducer, bqConsumer, currentStateDisplayName);
+ dispSurface = vds;
+ producer = vds;
+#ifdef QTI_BSP
+ }
+#endif
+}
+
+bool DisplayUtils::createV4L2BasedVirtualDisplay(HWComposer* hwc, int32_t &hwcDisplayId,
+ sp<DisplaySurface> &dispSurface, sp<IGraphicBufferProducer> &producer,
+ sp<IGraphicBufferProducer> currentStateSurface,
+ sp<IGraphicBufferProducer> bqProducer, sp<IGraphicBufferConsumer> bqConsumer,
+ int currentStateType) {
+ char value[PROPERTY_VALUE_MAX];
+ property_get("persist.sys.wfd.virtual", value, "0");
+ int wfdVirtual = atoi(value);
+ if(wfdVirtual && hwcDisplayId > 0) {
+ //Read virtual display properties and create a
+ //rendering surface for it inorder to be handled
+ //by hwc.
+
+ sp<ANativeWindow> mNativeWindow = new Surface(currentStateSurface);
+ ANativeWindow* const window = mNativeWindow.get();
+
+ int format;
+ window->query(window, NATIVE_WINDOW_FORMAT, &format);
+ EGLSurface surface;
+ EGLint w, h;
+ EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ // In M AOSP getEGLConfig() always returns EGL_NO_CONFIG as
+ // EGL_ANDROIDX_no_config_context active now.
+ EGLConfig config = RenderEngine::chooseEglConfig(display, format);
+
+ surface = eglCreateWindowSurface(display, config, window, NULL);
+ eglQuerySurface(display, surface, EGL_WIDTH, &w);
+ eglQuerySurface(display, surface, EGL_HEIGHT, &h);
+ if(hwc->setVirtualDisplayProperties(hwcDisplayId, w, h, format) != NO_ERROR)
+ return false;
+
+ dispSurface = new FramebufferSurface(*hwc, currentStateType, bqConsumer);
+ producer = bqProducer;
+ return true;
+ }
+ return false;
+}
+
+}; // namespace android
+
diff --git a/services/surfaceflinger/DisplayUtils.h b/services/surfaceflinger/DisplayUtils.h
new file mode 100644
index 0000000..cdf2b67
--- /dev/null
+++ b/services/surfaceflinger/DisplayUtils.h
@@ -0,0 +1,78 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ANDROID_DISPLAY_UTILS_H
+#define ANDROID_DISPLAY_UTILS_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include "Layer.h"
+#include "SurfaceFlinger.h"
+#include "DisplayHardware/HWComposer.h"
+#include "DisplayHardware/VirtualDisplaySurface.h"
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+class IGraphicBufferProducer;
+class IGraphicBufferConsumer;
+class DisplaySurface;
+
+/* Factory Classes */
+
+class DisplayUtils {
+ public:
+ static DisplayUtils* getInstance() ANDROID_API;
+ SurfaceFlinger* getSFInstance() ANDROID_API;
+ Layer* getLayerInstance(SurfaceFlinger*, const sp<Client>&,
+ const String8&, uint32_t,
+ uint32_t, uint32_t);
+ HWComposer* getHWCInstance(const sp<SurfaceFlinger>& flinger,
+ HWComposer::EventHandler& handler);
+ void initVDSInstance(HWComposer* hwc, int32_t hwcDisplayId,
+ sp<IGraphicBufferProducer> currentStateSurface, sp<DisplaySurface> &dispSurface,
+ sp<IGraphicBufferProducer> &producer, sp<IGraphicBufferProducer> bqProducer,
+ sp<IGraphicBufferConsumer> bqConsumer, String8 currentStateDisplayName,
+ bool currentStateIsSecure, int currentStateType);
+ DisplayUtils();
+ private:
+ static DisplayUtils* sDisplayUtils;
+ static bool sUseExtendedImpls;
+
+ bool createV4L2BasedVirtualDisplay(HWComposer* hwc, int32_t &hwcDisplayId,
+ sp<DisplaySurface> &dispSurface, sp<IGraphicBufferProducer> &producer,
+ sp<IGraphicBufferProducer> currentStateSurface,
+ sp<IGraphicBufferProducer> bqProducer,
+ sp<IGraphicBufferConsumer> bqConsumer, int currentStateType);
+};
+
+}; // namespace android
+
+#endif // ANDROID_DISPLAY_UTILS_H
diff --git a/services/surfaceflinger/EventThread.cpp b/services/surfaceflinger/EventThread.cpp
index f760200..973a8bc 100644
--- a/services/surfaceflinger/EventThread.cpp
+++ b/services/surfaceflinger/EventThread.cpp
@@ -20,6 +20,7 @@
#include <sys/types.h>
#include <cutils/compiler.h>
+#include <cutils/iosched_policy.h>
#include <gui/BitTube.h>
#include <gui/IDisplayEventConnection.h>
@@ -91,6 +92,7 @@ void EventThread::sendVsyncHintOnLocked() {
void EventThread::onFirstRef() {
run("EventThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
+ android_set_rt_ioprio(getTid(), 1);
}
sp<EventThread::Connection> EventThread::createEventConnection() const {
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 5ff79a9..bcd5915 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -320,7 +320,7 @@ Rect Layer::getContentCrop() const {
return crop;
}
-static Rect reduce(const Rect& win, const Region& exclude) {
+Rect Layer::reduce(const Rect& win, const Region& exclude) const{
if (CC_LIKELY(exclude.isEmpty())) {
return win;
}
@@ -494,6 +494,7 @@ void Layer::setGeometry(
frame.intersect(hw->getViewport(), &frame);
const Transform& tr(hw->getTransform());
layer.setFrame(tr.transform(frame));
+ setPosition(hw, layer, s);
layer.setCrop(computeCrop(hw));
layer.setPlaneAlpha(s.alpha);
@@ -578,6 +579,7 @@ void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
}
}
}
+ setAcquiredFenceIfBlit(fenceFd, layer);
layer.setAcquireFenceFd(fenceFd);
}
@@ -664,7 +666,7 @@ void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
RenderEngine& engine(mFlinger->getRenderEngine());
- if (!blackOutLayer) {
+ if (!blackOutLayer || canAllowGPUForProtected()) {
// TODO: we could be more subtle with isFixedSize()
const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index c1e5e9f..c0c8bf5 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -71,6 +71,9 @@ class Layer : public SurfaceFlingerConsumer::ContentsChangedListener {
static int32_t sSequence;
public:
+#ifdef QTI_BSP
+ friend class ExLayer;
+#endif
mutable bool contentDirty;
// regions below are in window-manager space
Region visibleRegion;
@@ -204,7 +207,7 @@ public:
void setGeometry(const sp<const DisplayDevice>& hw,
HWComposer::HWCLayerInterface& layer);
- void setPerFrameData(const sp<const DisplayDevice>& hw,
+ virtual void setPerFrameData(const sp<const DisplayDevice>& hw,
HWComposer::HWCLayerInterface& layer);
void setAcquireFence(const sp<const DisplayDevice>& hw,
HWComposer::HWCLayerInterface& layer);
@@ -285,6 +288,21 @@ public:
// the current orientation of the display device.
void updateTransformHint(const sp<const DisplayDevice>& hw) const;
+ /* ------------------------------------------------------------------------
+ * Extensions
+ */
+ virtual bool isExtOnly() const { return false; }
+ virtual bool isIntOnly() const { return false; }
+ virtual bool isSecureDisplay() const { return false; }
+ virtual bool isYuvLayer() const { return false; }
+ virtual void setPosition(const sp<const DisplayDevice>& /*hw*/,
+ HWComposer::HWCLayerInterface& /*layer*/,
+ const State& /*state*/) { }
+ virtual void setAcquiredFenceIfBlit(int& /*fenceFd */,
+ HWComposer::HWCLayerInterface& /*layer */) { }
+ virtual bool canAllowGPUForProtected() const { return false; }
+
+
/*
* returns the rectangle that crops the content of the layer and scales it
* to the layer's size.
@@ -336,6 +354,7 @@ protected:
LayerCleaner(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer);
};
+ Rect reduce(const Rect& win, const Region& exclude) const;
private:
// Interface implementation for SurfaceFlingerConsumer::ContentsChangedListener
diff --git a/services/surfaceflinger/LayerDim.cpp b/services/surfaceflinger/LayerDim.cpp
index 14aa328..b8d549a 100644
--- a/services/surfaceflinger/LayerDim.cpp
+++ b/services/surfaceflinger/LayerDim.cpp
@@ -58,6 +58,15 @@ bool LayerDim::isVisible() const {
return !(s.flags & layer_state_t::eLayerHidden) && s.alpha;
}
+void LayerDim::setPerFrameData(const sp<const DisplayDevice>& hw,
+ HWComposer::HWCLayerInterface& layer) {
+ HWComposer& hwc = mFlinger->getHwComposer();
+
+ Layer::setPerFrameData(hw, layer);
+ if (hwc.hasDimComposition()) {
+ layer.setDim();
+ }
+}
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/LayerDim.h b/services/surfaceflinger/LayerDim.h
index a0cfca9..b66591b 100644
--- a/services/surfaceflinger/LayerDim.h
+++ b/services/surfaceflinger/LayerDim.h
@@ -40,6 +40,8 @@ public:
virtual bool isSecure() const { return false; }
virtual bool isFixedSize() const { return true; }
virtual bool isVisible() const;
+ virtual void setPerFrameData(const sp<const DisplayDevice>& hw,
+ HWComposer::HWCLayerInterface& layer);
};
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp
index 1a9f59b..853a4eb 100644
--- a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp
@@ -92,14 +92,29 @@ void GLES11RenderEngine::setViewportAndProjection(
case Transform::ROT_0:
break;
case Transform::ROT_90:
- glRotatef(90, 0, 0, 1);
+ {
+ float x1 = (l+r)/2;
+ float y1 = (t+b)/2;
+ glTranslatef(x1-y1, x1+y1, 0);
+ glRotatef(270, 0, 0, 1);
break;
+ }
case Transform::ROT_180:
+ {
+ float x1 = (l+r)/2;
+ float y1 = (t+b)/2;
+ glTranslatef(x1*2, y1*2, 0);
glRotatef(180, 0, 0, 1);
break;
+ }
case Transform::ROT_270:
- glRotatef(270, 0, 0, 1);
+ {
+ float x1 = (l+r)/2;
+ float y1 = (t+b)/2;
+ glTranslatef(x1+y1, y1-x1, 0);
+ glRotatef(90, 0, 0, 1);
break;
+ }
default:
break;
}
@@ -210,28 +225,46 @@ void GLES11RenderEngine::disableBlending() {
}
void GLES11RenderEngine::bindImageAsFramebuffer(EGLImageKHR image,
- uint32_t* texName, uint32_t* fbName, uint32_t* status) {
+ uint32_t* texName, uint32_t* fbName, uint32_t* status,
+ bool useReadPixels, int reqWidth, int reqHeight) {
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);
+ if (!useReadPixels) {
+ // 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);
+ } else {
+ // since we're going to use glReadPixels() anyways,
+ // use an intermediate renderbuffer instead
+ glGenRenderbuffersOES(1, &tname);
+ glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
+ glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, reqWidth, reqHeight);
+ // create a FBO to render into
+ glGenFramebuffersOES(1, &name);
+ glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
+ glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES,
+ GL_RENDERBUFFER_OES, tname);
+ }
*status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
*texName = tname;
*fbName = name;
}
-void GLES11RenderEngine::unbindFramebuffer(uint32_t texName, uint32_t fbName) {
+void GLES11RenderEngine::unbindFramebuffer(uint32_t texName, uint32_t fbName,
+ bool useReadPixels) {
glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
glDeleteFramebuffersOES(1, &fbName);
- glDeleteTextures(1, &texName);
+ if (!useReadPixels)
+ glDeleteTextures(1, &texName);
+ else
+ glDeleteRenderbuffersOES(1, &texName);
}
void GLES11RenderEngine::setupFillWithColor(float r, float g, float b, float a) {
diff --git a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h
index 08de646..77824ce 100644
--- a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h
@@ -40,8 +40,9 @@ class GLES11RenderEngine : public RenderEngine {
GLint mMaxTextureSize;
virtual void bindImageAsFramebuffer(EGLImageKHR image,
- uint32_t* texName, uint32_t* fbName, uint32_t* status);
- virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName);
+ uint32_t* texName, uint32_t* fbName, uint32_t* status, bool useReadPixels,
+ int reqWidth, int reqHeight);
+ virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName, bool useReadPixels);
public:
GLES11RenderEngine();
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
index 1fabaf5..a35aa78 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
@@ -185,27 +185,44 @@ void GLES20RenderEngine::disableBlending() {
void GLES20RenderEngine::bindImageAsFramebuffer(EGLImageKHR image,
- uint32_t* texName, uint32_t* fbName, uint32_t* status) {
+ uint32_t* texName, uint32_t* fbName, uint32_t* status,
+ bool useReadPixels, int reqWidth, int reqHeight) {
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
- glGenFramebuffers(1, &name);
- glBindFramebuffer(GL_FRAMEBUFFER, name);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tname, 0);
+ if (!useReadPixels) {
+ // 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
+ glGenFramebuffers(1, &name);
+ glBindFramebuffer(GL_FRAMEBUFFER, name);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tname, 0);
+ } else {
+ // since we're going to use glReadPixels() anyways,
+ // use an intermediate renderbuffer instead
+ glGenRenderbuffers(1, &tname);
+ glBindRenderbuffer(GL_RENDERBUFFER, tname);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8_OES, reqWidth, reqHeight);
+ // create a FBO to render into
+ glGenFramebuffers(1, &name);
+ glBindFramebuffer(GL_FRAMEBUFFER, name);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, tname);
+ }
*status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
*texName = tname;
*fbName = name;
}
-void GLES20RenderEngine::unbindFramebuffer(uint32_t texName, uint32_t fbName) {
+void GLES20RenderEngine::unbindFramebuffer(uint32_t texName, uint32_t fbName,
+ bool useReadPixels) {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDeleteFramebuffers(1, &fbName);
- glDeleteTextures(1, &texName);
+ if (!useReadPixels)
+ glDeleteTextures(1, &texName);
+ else
+ glDeleteRenderbuffers(1, &texName);
}
void GLES20RenderEngine::setupFillWithColor(float r, float g, float b, float a) {
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
index 819356a..6074a3d 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
@@ -55,8 +55,9 @@ class GLES20RenderEngine : public RenderEngine {
Vector<Group> mGroupStack;
virtual void bindImageAsFramebuffer(EGLImageKHR image,
- uint32_t* texName, uint32_t* fbName, uint32_t* status);
- virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName);
+ uint32_t* texName, uint32_t* fbName, uint32_t* status,
+ bool useReadPixels, int reqWidth, int reqHeight);
+ virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName, bool useReadPixels);
public:
GLES20RenderEngine();
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.cpp b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
index 7cd42e4..cb1d14c 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
@@ -83,7 +83,6 @@ RenderEngine* RenderEngine::create(EGLDisplay display, int hwcFormat) {
EGL_CONTEXT_CLIENT_VERSION, contextClientVersion, // MUST be first
#ifdef EGL_IMG_context_priority
#ifdef HAS_CONTEXT_PRIORITY
-#warning "using EGL_IMG_context_priority"
EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG,
#endif
#endif
@@ -262,9 +261,11 @@ void RenderEngine::dump(String8& result) {
// ---------------------------------------------------------------------------
RenderEngine::BindImageAsFramebuffer::BindImageAsFramebuffer(
- RenderEngine& engine, EGLImageKHR image) : mEngine(engine)
+ RenderEngine& engine, EGLImageKHR image, bool useReadPixels,
+ int reqWidth, int reqHeight) : mEngine(engine), mUseReadPixels(useReadPixels)
{
- mEngine.bindImageAsFramebuffer(image, &mTexName, &mFbName, &mStatus);
+ mEngine.bindImageAsFramebuffer(image, &mTexName, &mFbName, &mStatus,
+ useReadPixels, reqWidth, reqHeight);
ALOGE_IF(mStatus != GL_FRAMEBUFFER_COMPLETE_OES,
"glCheckFramebufferStatusOES error %d", mStatus);
@@ -272,7 +273,7 @@ RenderEngine::BindImageAsFramebuffer::BindImageAsFramebuffer(
RenderEngine::BindImageAsFramebuffer::~BindImageAsFramebuffer() {
// back to main framebuffer
- mEngine.unbindFramebuffer(mTexName, mFbName);
+ mEngine.unbindFramebuffer(mTexName, mFbName, mUseReadPixels);
}
status_t RenderEngine::BindImageAsFramebuffer::getStatus() const {
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.h b/services/surfaceflinger/RenderEngine/RenderEngine.h
index 31a961e..c9a043a 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.h
@@ -51,8 +51,11 @@ class RenderEngine {
EGLContext mEGLContext;
void setEGLHandles(EGLConfig config, EGLContext ctxt);
- virtual void bindImageAsFramebuffer(EGLImageKHR image, uint32_t* texName, uint32_t* fbName, uint32_t* status) = 0;
- virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName) = 0;
+ virtual void bindImageAsFramebuffer(EGLImageKHR image, uint32_t* texName,
+ uint32_t* fbName, uint32_t* status, bool useReadPixels, int reqWidth,
+ int reqHeight) = 0;
+ virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName,
+ bool useReadPixels) = 0;
protected:
RenderEngine();
@@ -83,8 +86,10 @@ public:
RenderEngine& mEngine;
uint32_t mTexName, mFbName;
uint32_t mStatus;
+ bool mUseReadPixels;
public:
- BindImageAsFramebuffer(RenderEngine& engine, EGLImageKHR image);
+ BindImageAsFramebuffer(RenderEngine& engine, EGLImageKHR image,
+ bool useReadPixels, int reqWidth, int reqHeight);
~BindImageAsFramebuffer();
int getStatus() const;
};
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index fdc3650..fc99fa0 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -27,6 +27,7 @@
#include <EGL/egl.h>
#include <cutils/log.h>
+#include <cutils/iosched_policy.h>
#include <cutils/properties.h>
#include <binder/IPCThreadState.h>
@@ -77,6 +78,7 @@
#include "RenderEngine/RenderEngine.h"
#include <cutils/compiler.h>
+#include "DisplayUtils.h"
#define DISPLAY_COUNT 1
@@ -122,6 +124,8 @@ const String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"
const String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER");
const String16 sDump("android.permission.DUMP");
+static sp<Layer> lastSurfaceViewLayer;
+
// ---------------------------------------------------------------------------
SurfaceFlinger::SurfaceFlinger()
@@ -456,7 +460,7 @@ void SurfaceFlinger::init() {
// Initialize the H/W composer object. There may or may not be an
// actual hardware composer underneath.
- mHwc = new HWComposer(this,
+ mHwc = DisplayUtils::getInstance()->getHWCInstance(this,
*static_cast<HWComposer::EventHandler *>(this));
// get a RenderEngine for the given display / config (can't fail)
@@ -497,6 +501,13 @@ void SurfaceFlinger::init() {
ALOGD("marking display %zu as acquired/unblanked", i);
hw->setPowerMode(HWC_POWER_MODE_NORMAL);
}
+ // When a non-virtual display device is added at boot time,
+ // update the active config by querying HWC otherwise the
+ // default config (config 0) will be used.
+ int activeConfig = mHwc->getActiveConfig(hwcId);
+ if (activeConfig >= 0) {
+ hw->setActiveConfig(activeConfig);
+ }
mDisplays.add(token, hw);
}
}
@@ -507,6 +518,7 @@ void SurfaceFlinger::init() {
mEventControlThread = new EventControlThread(this);
mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
+ android_set_rt_ioprio(mEventControlThread->getTid(), 1);
// set a fake vsync period if there is no HWComposer
if (mHwc->initCheck() != NO_ERROR) {
@@ -695,8 +707,10 @@ void SurfaceFlinger::setActiveConfigInternal(const sp<DisplayDevice>& hw, int mo
return;
}
- hw->setActiveConfig(mode);
- getHwComposer().setActiveConfig(type, mode);
+ status_t status = getHwComposer().setActiveConfig(type, mode);
+ if (status == NO_ERROR) {
+ hw->setActiveConfig(mode);
+ }
}
status_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& display, int mode) {
@@ -869,6 +883,7 @@ void SurfaceFlinger::onHotplugReceived(int type, bool connected) {
} else {
mCurrentState.displays.removeItem(mBuiltinDisplays[type]);
mBuiltinDisplays[type].clear();
+ updateVisibleRegionsDirty();
}
setTransactionFlags(eDisplayTransactionNeeded);
@@ -1067,6 +1082,7 @@ void SurfaceFlinger::postComposition()
}
void SurfaceFlinger::rebuildLayerStacks() {
+ updateExtendedMode();
// rebuild the visible layer list per screen
if (CC_UNLIKELY(mVisibleRegionsDirty)) {
ATRACE_CALL();
@@ -1082,14 +1098,13 @@ void SurfaceFlinger::rebuildLayerStacks() {
const Transform& tr(hw->getTransform());
const Rect bounds(hw->getBounds());
if (hw->isDisplayOn()) {
- SurfaceFlinger::computeVisibleRegions(layers,
+ computeVisibleRegions(hw->getHwcDisplayId(), layers,
hw->getLayerStack(), dirtyRegion, opaqueRegion);
const size_t count = layers.size();
for (size_t i=0 ; i<count ; i++) {
const sp<Layer>& layer(layers[i]);
- const Layer::State& s(layer->getDrawingState());
- if (s.layerStack == hw->getLayerStack()) {
+ {
Region drawRegion(tr.transform(
layer->visibleNonTransparentRegion));
drawRegion.andSelf(bounds);
@@ -1169,6 +1184,8 @@ void SurfaceFlinger::setUpHWComposer() {
sp<const DisplayDevice> hw(mDisplays[dpy]);
const int32_t id = hw->getHwcDisplayId();
if (id >= 0) {
+ bool freezeSurfacePresent = false;
+ isfreezeSurfacePresent(freezeSurfacePresent, hw, id);
const Vector< sp<Layer> >& currentLayers(
hw->getVisibleLayersSortedByZ());
const size_t count = currentLayers.size();
@@ -1181,6 +1198,11 @@ void SurfaceFlinger::setUpHWComposer() {
*/
const sp<Layer>& layer(currentLayers[i]);
layer->setPerFrameData(hw, *cur);
+ setOrientationEventControl(freezeSurfacePresent,id);
+ if(!strncmp(layer->getName(), "SurfaceView",
+ 11)) {
+ lastSurfaceViewLayer = layer;
+ }
}
}
}
@@ -1454,12 +1476,10 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
hwcDisplayId = allocateHwcDisplayId(state.type);
}
- sp<VirtualDisplaySurface> vds = new VirtualDisplaySurface(
- *mHwc, hwcDisplayId, state.surface,
- bqProducer, bqConsumer, state.displayName);
+ DisplayUtils::getInstance()->initVDSInstance(mHwc, hwcDisplayId,
+ state.surface, dispSurface, producer, bqProducer, bqConsumer,
+ state.displayName, state.isSecure, state.type);
- dispSurface = vds;
- producer = vds;
}
} else {
ALOGE_IF(state.surface!=NULL,
@@ -1475,7 +1495,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
}
const wp<IBinder>& display(curr.keyAt(i));
- if (dispSurface != NULL) {
+ if (dispSurface != NULL && producer != NULL) {
sp<DisplayDevice> hw = new DisplayDevice(this,
state.type, hwcDisplayId,
mHwc->getFormat(hwcDisplayId), state.isSecure,
@@ -1485,6 +1505,16 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
hw->setProjection(state.orientation,
state.viewport, state.frame);
hw->setDisplayName(state.displayName);
+ // When a new display device is added update the active
+ // config by querying HWC otherwise the default config
+ // (config 0) will be used.
+ if (hwcDisplayId >= DisplayDevice::DISPLAY_PRIMARY &&
+ hwcDisplayId < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
+ int activeConfig = mHwc->getActiveConfig(hwcDisplayId);
+ if (activeConfig >= 0) {
+ hw->setActiveConfig(activeConfig);
+ }
+ }
mDisplays.add(display, hw);
if (state.isVirtualDisplay()) {
if (hwcDisplayId >= 0) {
@@ -1643,7 +1673,7 @@ void SurfaceFlinger::commitTransaction()
mTransactionCV.broadcast();
}
-void SurfaceFlinger::computeVisibleRegions(
+void SurfaceFlinger::computeVisibleRegions(size_t dpy,
const LayerVector& currentLayers, uint32_t layerStack,
Region& outDirtyRegion, Region& outOpaqueRegion)
{
@@ -1654,6 +1684,9 @@ void SurfaceFlinger::computeVisibleRegions(
Region dirty;
outDirtyRegion.clear();
+ bool bIgnoreLayers = false;
+ int indexLOI = -1;
+ getIndexLOI(dpy, currentLayers, bIgnoreLayers, indexLOI);
size_t i = currentLayers.size();
while (i--) {
@@ -1662,8 +1695,9 @@ void SurfaceFlinger::computeVisibleRegions(
// start with the whole surface at its current location
const Layer::State& s(layer->getDrawingState());
- // only consider the layers on the given layer stack
- if (s.layerStack != layerStack)
+ if(updateLayerVisibleNonTransparentRegion(dpy, layer,
+ bIgnoreLayers, indexLOI,
+ layerStack, i))
continue;
/*
@@ -1954,7 +1988,7 @@ bool SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const
// screen is already cleared here
if (!region.isEmpty()) {
// can happen with SurfaceView
- drawWormhole(hw, region);
+ drawWormHoleIfRequired(cur, end, hw, region);
}
}
@@ -2096,6 +2130,8 @@ void SurfaceFlinger::setTransactionState(
uint32_t flags)
{
ATRACE_CALL();
+
+ delayDPTransactionIfNeeded(displays);
Mutex::Autolock _l(mStateLock);
uint32_t transactionFlags = 0;
@@ -2342,7 +2378,7 @@ status_t SurfaceFlinger::createNormalLayer(const sp<Client>& client,
break;
}
- *outLayer = new Layer(this, client, name, w, h, flags);
+ *outLayer = DisplayUtils::getInstance()->getLayerInstance(this, client, name, w, h, flags);
status_t err = (*outLayer)->setBuffers(w, h, format, flags);
if (err == NO_ERROR) {
*handle = (*outLayer)->getHandle();
@@ -2605,14 +2641,19 @@ void SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index
if (name.isEmpty()) {
mAnimFrameTracker.dumpStats(result);
} else {
+ bool found = false;
const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
const size_t count = currentLayers.size();
for (size_t i=0 ; i<count ; i++) {
const sp<Layer>& layer(currentLayers[i]);
if (name == layer->getName()) {
+ found = true;
layer->dumpFrameStats(result);
}
}
+ if (!found && !strncmp(name.string(), "SurfaceView", 11)) {
+ lastSurfaceViewLayer->dumpFrameStats(result);
+ }
}
}
@@ -3155,7 +3196,8 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
const sp<IGraphicBufferProducer>& producer,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
- bool useIdentityTransform, ISurfaceComposer::Rotation rotation) {
+ bool useIdentityTransform, ISurfaceComposer::Rotation rotation,
+ bool useReadPixels) {
if (CC_UNLIKELY(display == 0))
return BAD_VALUE;
@@ -3205,6 +3247,7 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
uint32_t minLayerZ,maxLayerZ;
bool useIdentityTransform;
Transform::orientation_flags rotation;
+ bool useReadPixels;
status_t result;
public:
MessageCaptureScreen(SurfaceFlinger* flinger,
@@ -3212,12 +3255,14 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
const sp<IGraphicBufferProducer>& producer,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
- bool useIdentityTransform, Transform::orientation_flags rotation)
+ bool useIdentityTransform, Transform::orientation_flags rotation,
+ bool useReadPixels)
: flinger(flinger), display(display), producer(producer),
sourceCrop(sourceCrop), reqWidth(reqWidth), reqHeight(reqHeight),
minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
useIdentityTransform(useIdentityTransform),
rotation(rotation),
+ useReadPixels(useReadPixels),
result(PERMISSION_DENIED)
{
}
@@ -3227,9 +3272,10 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
virtual bool handler() {
Mutex::Autolock _l(flinger->mStateLock);
sp<const DisplayDevice> hw(flinger->getDisplayDevice(display));
+ bool useReadPixels = this->useReadPixels && !flinger->mGpuToCpuSupported;
result = flinger->captureScreenImplLocked(hw, producer,
sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
- useIdentityTransform, rotation);
+ useIdentityTransform, rotation, useReadPixels);
static_cast<GraphicProducerWrapper*>(IInterface::asBinder(producer).get())->exit(result);
return true;
}
@@ -3252,7 +3298,7 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
sp<MessageBase> msg = new MessageCaptureScreen(this,
display, IGraphicBufferProducer::asInterface( wrapper ),
sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
- useIdentityTransform, rotationFlags);
+ useIdentityTransform, rotationFlags, useReadPixels);
status_t res = postMessageAsync(msg);
if (res == NO_ERROR) {
@@ -3301,6 +3347,12 @@ void SurfaceFlinger::renderScreenImplLocked(
// make sure to clear all GL error flags
engine.checkErrors();
+ if (DisplayDevice::DISPLAY_PRIMARY == hw->getDisplayType() &&
+ hw->isPanelInverseMounted()) {
+ rotation = (Transform::orientation_flags)
+ (rotation ^ Transform::ROT_180);
+ }
+
// set-up our viewport
engine.setViewportAndProjection(
reqWidth, reqHeight, sourceCrop, hw_h, yswap, rotation);
@@ -3316,7 +3368,7 @@ void SurfaceFlinger::renderScreenImplLocked(
const Layer::State& state(layer->getDrawingState());
if (state.layerStack == hw->getLayerStack()) {
if (state.z >= minLayerZ && state.z <= maxLayerZ) {
- if (layer->isVisible()) {
+ if (canDrawLayerinScreenShot(hw,layer)) {
if (filtering) layer->setFiltering(true);
layer->draw(hw, useIdentityTransform);
if (filtering) layer->setFiltering(false);
@@ -3336,7 +3388,8 @@ status_t SurfaceFlinger::captureScreenImplLocked(
const sp<IGraphicBufferProducer>& producer,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
- bool useIdentityTransform, Transform::orientation_flags rotation)
+ bool useIdentityTransform, Transform::orientation_flags rotation,
+ bool useReadPixels)
{
ATRACE_CALL();
@@ -3388,7 +3441,8 @@ status_t SurfaceFlinger::captureScreenImplLocked(
if (image != EGL_NO_IMAGE_KHR) {
// this binds the given EGLImage as a framebuffer for the
// duration of this scope.
- RenderEngine::BindImageAsFramebuffer imageBond(getRenderEngine(), image);
+ RenderEngine::BindImageAsFramebuffer imageBond(getRenderEngine(), image,
+ useReadPixels, reqWidth, reqHeight);
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
@@ -3435,6 +3489,15 @@ status_t SurfaceFlinger::captureScreenImplLocked(
ALOGW("captureScreen: error creating EGL fence: %#x", eglGetError());
}
}
+ if (useReadPixels) {
+ sp<GraphicBuffer> buf = static_cast<GraphicBuffer*>(buffer);
+ void* vaddr;
+ if (buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, &vaddr) == NO_ERROR) {
+ getRenderEngine().readPixels(0, 0, buffer->stride, reqHeight,
+ (uint32_t *)vaddr);
+ buf->unlock();
+ }
+ }
if (DEBUG_SCREENSHOTS) {
uint32_t* pixels = new uint32_t[reqWidth*reqHeight];
getRenderEngine().readPixels(0, 0, reqWidth, reqHeight, pixels);
@@ -3492,6 +3555,44 @@ void SurfaceFlinger::checkScreenshot(size_t w, size_t s, size_t h, void const* v
}
}
+/* ------------------------------------------------------------------------
+ * Extensions
+ */
+
+bool SurfaceFlinger::updateLayerVisibleNonTransparentRegion(const int& /*dpy*/,
+ const sp<Layer>& layer, bool& /*bIgnoreLayers*/, int& /*indexLOI*/,
+ uint32_t layerStack, const int& /*i*/) {
+
+ const Layer::State& s(layer->getDrawingState());
+
+ // only consider the layers on the given layer stack
+ if (s.layerStack != layerStack) {
+ /* set the visible region as empty since we have removed the
+ * layerstack check in rebuildLayerStack() function
+ */
+ Region visibleNonTransRegion;
+ visibleNonTransRegion.set(Rect(0,0));
+ layer->setVisibleNonTransparentRegion(visibleNonTransRegion);
+
+ return true;
+ }
+
+ return false;
+}
+
+bool SurfaceFlinger::canDrawLayerinScreenShot(
+ const sp<const DisplayDevice>& /*hw*/,
+ const sp<Layer>& layer) {
+ return layer->isVisible();
+}
+
+void SurfaceFlinger::drawWormHoleIfRequired(HWComposer::LayerListIterator& /*cur*/,
+ const HWComposer::LayerListIterator& /*end*/,
+ const sp<const DisplayDevice>& hw,
+ const Region& region) {
+ drawWormhole(hw, region);
+}
+
// ---------------------------------------------------------------------------
SurfaceFlinger::LayerVector::LayerVector() {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index b3baadd..4bbb1f4 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -84,6 +84,10 @@ class SurfaceFlinger : public BnSurfaceComposer,
private HWComposer::EventHandler
{
public:
+#ifdef QTI_BSP
+ friend class ExSurfaceFlinger;
+#endif
+
static char const* getServiceName() ANDROID_API {
return "SurfaceFlinger";
}
@@ -138,6 +142,7 @@ private:
friend class Client;
friend class DisplayEventConnection;
friend class Layer;
+ friend class LayerDim;
friend class MonitoredProducer;
// This value is specified in number of frames. Log frame stats at most
@@ -207,7 +212,8 @@ private:
const sp<IGraphicBufferProducer>& producer,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
- bool useIdentityTransform, ISurfaceComposer::Rotation rotation);
+ bool useIdentityTransform, ISurfaceComposer::Rotation rotation,
+ bool isCpuConsumer);
virtual status_t getDisplayStats(const sp<IBinder>& display,
DisplayStatInfo* stats);
virtual status_t getDisplayConfigs(const sp<IBinder>& display,
@@ -235,6 +241,43 @@ private:
virtual void onHotplugReceived(int disp, bool connected);
/* ------------------------------------------------------------------------
+ * Extensions
+ */
+ virtual void updateExtendedMode() { }
+
+ virtual void getIndexLOI(size_t /*dpy*/,
+ const LayerVector& /*currentLayers*/,
+ bool& /*bIgnoreLayers*/,
+ int& /*indexLOI*/) { }
+
+ virtual bool updateLayerVisibleNonTransparentRegion(
+ const int& dpy, const sp<Layer>& layer,
+ bool& bIgnoreLayers, int& indexLOI,
+ uint32_t layerStack, const int& i);
+
+ virtual void delayDPTransactionIfNeeded(
+ const Vector<DisplayState>& /*displays*/) { }
+
+ virtual bool canDrawLayerinScreenShot(
+ const sp<const DisplayDevice>& hw,
+ const sp<Layer>& layer);
+
+ virtual void isfreezeSurfacePresent(
+ bool& freezeSurfacePresent,
+ const sp<const DisplayDevice>& /*hw*/,
+ const int32_t& /*id*/) { freezeSurfacePresent = false; }
+
+ virtual void setOrientationEventControl(
+ bool& /*freezeSurfacePresent*/,
+ const int32_t& /*id*/) { }
+
+ virtual void updateVisibleRegionsDirty() { }
+
+ virtual void drawWormHoleIfRequired(HWComposer::LayerListIterator &cur,
+ const HWComposer::LayerListIterator &end,
+ const sp<const DisplayDevice>& hw,
+ const Region& region);
+ /* ------------------------------------------------------------------------
* Message handling
*/
void waitForEvent();
@@ -329,7 +372,8 @@ private:
const sp<IGraphicBufferProducer>& producer,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
- bool useIdentityTransform, Transform::orientation_flags rotation);
+ bool useIdentityTransform, Transform::orientation_flags rotation,
+ bool useReadPixels);
/* ------------------------------------------------------------------------
* EGL
@@ -373,7 +417,7 @@ private:
* Compositing
*/
void invalidateHwcGeometry();
- static void computeVisibleRegions(
+ void computeVisibleRegions(size_t dpy,
const LayerVector& currentLayers, uint32_t layerStack,
Region& dirtyRegion, Region& opaqueRegion);
diff --git a/services/surfaceflinger/main_surfaceflinger.cpp b/services/surfaceflinger/main_surfaceflinger.cpp
index a74bc4c..6127cf6 100644
--- a/services/surfaceflinger/main_surfaceflinger.cpp
+++ b/services/surfaceflinger/main_surfaceflinger.cpp
@@ -22,6 +22,7 @@
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include "SurfaceFlinger.h"
+#include "DisplayUtils.h"
using namespace android;
@@ -35,7 +36,7 @@ int main(int, char**) {
ps->startThreadPool();
// instantiate surfaceflinger
- sp<SurfaceFlinger> flinger = new SurfaceFlinger();
+ sp<SurfaceFlinger> flinger = DisplayUtils::getInstance()->getSFInstance();
setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);