Merge "SF: Set the buffer size immediately when applying a transaction"
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 2c248c6..9216e75 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1464,6 +1464,12 @@
DUMPSYS_COMPONENTS_OPTIONS);
printf("========================================================\n");
+ printf("== Checkins\n");
+ printf("========================================================\n");
+
+ RunDumpsys("CHECKIN BATTERYSTATS", {"batterystats", "-c"});
+
+ printf("========================================================\n");
printf("== dumpstate: done (id %d)\n", ds.id_);
printf("========================================================\n");
}
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 7f9668f..81f692d 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -331,6 +331,34 @@
return result;
}
+ virtual status_t getDisplayViewport(const sp<IBinder>& display, Rect* outViewport) {
+ Parcel data, reply;
+ status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+ if (result != NO_ERROR) {
+ ALOGE("getDisplayViewport failed to writeInterfaceToken: %d", result);
+ return result;
+ }
+ result = data.writeStrongBinder(display);
+ if (result != NO_ERROR) {
+ ALOGE("getDisplayViewport failed to writeStrongBinder: %d", result);
+ return result;
+ }
+ result = remote()->transact(BnSurfaceComposer::GET_DISPLAY_VIEWPORT, data, &reply);
+ if (result != NO_ERROR) {
+ ALOGE("getDisplayViewport failed to transact: %d", result);
+ return result;
+ }
+ result = reply.readInt32();
+ if (result == NO_ERROR) {
+ result = reply.read(*outViewport);
+ if (result != NO_ERROR) {
+ ALOGE("getDisplayViewport failed to read: %d", result);
+ return result;
+ }
+ }
+ return result;
+ }
+
virtual int getActiveConfig(const sp<IBinder>& display)
{
Parcel data, reply;
@@ -747,6 +775,26 @@
}
return NO_ERROR;
}
+ case GET_DISPLAY_VIEWPORT: {
+ CHECK_INTERFACE(ISurfaceComposer, data, reply);
+ Rect outViewport;
+ sp<IBinder> display = nullptr;
+ status_t result = data.readStrongBinder(&display);
+ if (result != NO_ERROR) {
+ ALOGE("getDisplayViewport failed to readStrongBinder: %d", result);
+ return result;
+ }
+ result = getDisplayViewport(display, &outViewport);
+ result = reply->writeInt32(result);
+ if (result == NO_ERROR) {
+ result = reply->write(outViewport);
+ if (result != NO_ERROR) {
+ ALOGE("getDisplayViewport failed to write: %d", result);
+ return result;
+ }
+ }
+ return NO_ERROR;
+ }
case GET_ACTIVE_CONFIG: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
sp<IBinder> display = data.readStrongBinder();
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index d0ac8de..b8465e3 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -839,6 +839,10 @@
return NO_ERROR;
}
+status_t SurfaceComposerClient::getDisplayViewport(const sp<IBinder>& display, Rect* outViewport) {
+ return ComposerService::getComposerService()->getDisplayViewport(display, outViewport);
+}
+
int SurfaceComposerClient::getActiveConfig(const sp<IBinder>& display) {
return ComposerService::getComposerService()->getActiveConfig(display);
}
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index 98ec338..b9158f1 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -157,6 +157,9 @@
virtual status_t getDisplayStats(const sp<IBinder>& display,
DisplayStatInfo* stats) = 0;
+ /* returns display viewport information of the given display */
+ virtual status_t getDisplayViewport(const sp<IBinder>& display, Rect* outViewport) = 0;
+
/* indicates which of the configurations returned by getDisplayInfo is
* currently active */
virtual int getActiveConfig(const sp<IBinder>& display) = 0;
@@ -250,7 +253,8 @@
ENABLE_VSYNC_INJECTIONS,
INJECT_VSYNC,
GET_LAYER_DEBUG_INFO,
- CREATE_SCOPED_CONNECTION
+ CREATE_SCOPED_CONNECTION,
+ GET_DISPLAY_VIEWPORT
};
virtual status_t onTransact(uint32_t code, const Parcel& data,
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 4907866..9bd1131 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -79,6 +79,9 @@
static status_t getDisplayInfo(const sp<IBinder>& display,
DisplayInfo* info);
+ // Get the display viewport for the given display
+ static status_t getDisplayViewport(const sp<IBinder>& display, Rect* outViewport);
+
// Get the index of the current active configuration (relative to the list
// returned by getDisplayInfo)
static int getActiveConfig(const sp<IBinder>& display);
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 3542aba..f22e702 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -581,6 +581,9 @@
Vector<DisplayInfo>* /*configs*/) override { return NO_ERROR; }
status_t getDisplayStats(const sp<IBinder>& /*display*/,
DisplayStatInfo* /*stats*/) override { return NO_ERROR; }
+ status_t getDisplayViewport(const sp<IBinder>& /*display*/, Rect* /*outViewport*/) override {
+ return NO_ERROR;
+ }
int getActiveConfig(const sp<IBinder>& /*display*/) override { return 0; }
status_t setActiveConfig(const sp<IBinder>& /*display*/, int /*id*/)
override {
diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp
index beda75a..a4f83b7 100644
--- a/services/inputflinger/InputReader.cpp
+++ b/services/inputflinger/InputReader.cpp
@@ -3089,6 +3089,7 @@
InputMapper(device),
mSource(0), mDeviceMode(DEVICE_MODE_DISABLED),
mSurfaceWidth(-1), mSurfaceHeight(-1), mSurfaceLeft(0), mSurfaceTop(0),
+ mPhysicalWidth(-1), mPhysicalHeight(-1), mPhysicalLeft(0), mPhysicalTop(0),
mSurfaceOrientation(DISPLAY_ORIENTATION_0) {
}
@@ -3596,6 +3597,11 @@
break;
}
+ mPhysicalWidth = naturalPhysicalWidth;
+ mPhysicalHeight = naturalPhysicalHeight;
+ mPhysicalLeft = naturalPhysicalLeft;
+ mPhysicalTop = naturalPhysicalTop;
+
mSurfaceWidth = naturalLogicalWidth * naturalDeviceWidth / naturalPhysicalWidth;
mSurfaceHeight = naturalLogicalHeight * naturalDeviceHeight / naturalPhysicalHeight;
mSurfaceLeft = naturalPhysicalLeft * naturalLogicalWidth / naturalPhysicalWidth;
@@ -3604,6 +3610,11 @@
mSurfaceOrientation = mParameters.orientationAware ?
mViewport.orientation : DISPLAY_ORIENTATION_0;
} else {
+ mPhysicalWidth = rawWidth;
+ mPhysicalHeight = rawHeight;
+ mPhysicalLeft = 0;
+ mPhysicalTop = 0;
+
mSurfaceWidth = rawWidth;
mSurfaceHeight = rawHeight;
mSurfaceLeft = 0;
@@ -3914,6 +3925,10 @@
dump += StringPrintf(INDENT3 "SurfaceHeight: %dpx\n", mSurfaceHeight);
dump += StringPrintf(INDENT3 "SurfaceLeft: %d\n", mSurfaceLeft);
dump += StringPrintf(INDENT3 "SurfaceTop: %d\n", mSurfaceTop);
+ dump += StringPrintf(INDENT3 "PhysicalWidth: %dpx\n", mPhysicalWidth);
+ dump += StringPrintf(INDENT3 "PhysicalHeight: %dpx\n", mPhysicalHeight);
+ dump += StringPrintf(INDENT3 "PhysicalLeft: %d\n", mPhysicalLeft);
+ dump += StringPrintf(INDENT3 "PhysicalTop: %d\n", mPhysicalTop);
dump += StringPrintf(INDENT3 "SurfaceOrientation: %d\n", mSurfaceOrientation);
}
@@ -5120,10 +5135,10 @@
}
break;
case DISPLAY_ORIENTATION_180:
- x = float(mRawPointerAxes.x.maxValue - xTransformed) * mXScale + mXTranslate;
+ x = float(mRawPointerAxes.x.maxValue - xTransformed) * mXScale;
y = float(mRawPointerAxes.y.maxValue - yTransformed) * mYScale + mYTranslate;
- left = float(mRawPointerAxes.x.maxValue - rawRight) * mXScale + mXTranslate;
- right = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale + mXTranslate;
+ left = float(mRawPointerAxes.x.maxValue - rawRight) * mXScale;
+ right = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale;
bottom = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale + mYTranslate;
top = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale + mYTranslate;
orientation -= M_PI;
@@ -5132,10 +5147,10 @@
}
break;
case DISPLAY_ORIENTATION_270:
- x = float(mRawPointerAxes.y.maxValue - yTransformed) * mYScale + mYTranslate;
+ x = float(mRawPointerAxes.y.maxValue - yTransformed) * mYScale;
y = float(xTransformed - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
- left = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale + mYTranslate;
- right = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale + mYTranslate;
+ left = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale;
+ right = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale;
bottom = float(rawRight - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
top = float(rawLeft - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
orientation += M_PI_2;
@@ -6533,8 +6548,12 @@
}
bool TouchInputMapper::isPointInsideSurface(int32_t x, int32_t y) {
+ const float scaledX = x * mXScale;
+ const float scaledY = y * mYScale;
return x >= mRawPointerAxes.x.minValue && x <= mRawPointerAxes.x.maxValue
- && y >= mRawPointerAxes.y.minValue && y <= mRawPointerAxes.y.maxValue;
+ && scaledX >= mPhysicalLeft && scaledX <= mPhysicalLeft + mPhysicalWidth
+ && y >= mRawPointerAxes.y.minValue && y <= mRawPointerAxes.y.maxValue
+ && scaledY >= mPhysicalTop && scaledY <= mPhysicalTop + mPhysicalHeight;
}
const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHit(
diff --git a/services/inputflinger/InputReader.h b/services/inputflinger/InputReader.h
index 89290a8..af26b4f 100644
--- a/services/inputflinger/InputReader.h
+++ b/services/inputflinger/InputReader.h
@@ -1521,13 +1521,21 @@
// in the natural orientation.
// The surface origin specifies how the surface coordinates should be translated
// to align with the logical display coordinate space.
- // The orientation may be different from the viewport orientation as it specifies
- // the rotation of the surface coordinates required to produce the viewport's
- // requested orientation, so it will depend on whether the device is orientation aware.
int32_t mSurfaceWidth;
int32_t mSurfaceHeight;
int32_t mSurfaceLeft;
int32_t mSurfaceTop;
+
+ // Similar to the surface coordinates, but in the raw display coordinate space rather than in
+ // the logical coordinate space.
+ int32_t mPhysicalWidth;
+ int32_t mPhysicalHeight;
+ int32_t mPhysicalLeft;
+ int32_t mPhysicalTop;
+
+ // The orientation may be different from the viewport orientation as it specifies
+ // the rotation of the surface coordinates required to produce the viewport's
+ // requested orientation, so it will depend on whether the device is orientation aware.
int32_t mSurfaceOrientation;
// Translation and scaling factors, orientation-independent.
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index efaeaa2..05535a5 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -23,6 +23,7 @@
"android.hardware.configstore-utils",
"android.hardware.configstore@1.0",
"android.hardware.configstore@1.1",
+ "android.hardware.configstore@1.2",
"android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.composer@2.1",
"android.hardware.graphics.composer@2.2",
@@ -54,6 +55,7 @@
"libvulkan",
],
static_libs: [
+ "librenderengine",
"libserviceutils",
"libtrace_proto",
"libvkjson",
@@ -65,6 +67,7 @@
"android.hardware.graphics.composer@2.2-command-buffer",
],
export_static_lib_headers: [
+ "librenderengine",
"libserviceutils",
],
export_shared_lib_headers: [
@@ -117,16 +120,6 @@
"LayerVector.cpp",
"MonitoredProducer.cpp",
"RenderArea.cpp",
- "RenderEngine/Description.cpp",
- "RenderEngine/GLES20RenderEngine.cpp",
- "RenderEngine/GLExtensions.cpp",
- "RenderEngine/Image.cpp",
- "RenderEngine/Mesh.cpp",
- "RenderEngine/Program.cpp",
- "RenderEngine/ProgramCache.cpp",
- "RenderEngine/RenderEngine.cpp",
- "RenderEngine/Surface.cpp",
- "RenderEngine/Texture.cpp",
"Scheduler/DispSync.cpp",
"Scheduler/DispSyncSource.cpp",
"Scheduler/EventControlThread.cpp",
@@ -175,6 +168,7 @@
"android.frameworks.displayservice@1.0",
"android.hardware.configstore-utils",
"android.hardware.configstore@1.0",
+ "android.hardware.configstore@1.2",
"android.hardware.graphics.allocator@2.0",
"libbinder",
"libcutils",
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index e1094d8..d0ccabb 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -24,7 +24,7 @@
#include "DisplayDevice.h"
#include "LayerRejecter.h"
-#include "RenderEngine/RenderEngine.h"
+#include <renderengine/RenderEngine.h>
#include <gui/BufferItem.h>
#include <gui/BufferQueue.h>
@@ -275,6 +275,7 @@
to_string(error).c_str(), static_cast<int32_t>(error));
visible.dump(LOG_TAG);
}
+ getBE().compositionInfo.hwc.visibleRegion = visible;
error = hwcLayer->setSurfaceDamage(surfaceDamageRegion);
if (error != HWC2::Error::None) {
@@ -282,6 +283,7 @@
to_string(error).c_str(), static_cast<int32_t>(error));
surfaceDamageRegion.dump(LOG_TAG);
}
+ getBE().compositionInfo.hwc.surfaceDamage = surfaceDamageRegion;
// Sideband layers
if (getBE().compositionInfo.hwc.sidebandStream.get()) {
@@ -293,6 +295,7 @@
getBE().compositionInfo.hwc.sidebandStream->handle(), to_string(error).c_str(),
static_cast<int32_t>(error));
}
+ getBE().compositionInfo.compositionType = HWC2::Composition::Sideband;
return;
}
@@ -318,6 +321,9 @@
ALOGE("[%s] Failed to set hdrMetadata: %s (%d)", mName.string(),
to_string(error).c_str(), static_cast<int32_t>(error));
}
+ getBE().compositionInfo.hwc.dataspace = mCurrentDataSpace;
+ getBE().compositionInfo.hwc.hdrMetadata = getDrawingHdrMetadata();
+ getBE().compositionInfo.hwc.supportedPerFrameMetadata = display->getSupportedPerFrameMetadata();
setHwcLayerBuffer(display);
}
diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h
index 0b641b7..3319a98 100644
--- a/services/surfaceflinger/BufferLayer.h
+++ b/services/surfaceflinger/BufferLayer.h
@@ -24,13 +24,12 @@
#include "FrameTracker.h"
#include "LayerVector.h"
#include "MonitoredProducer.h"
-#include "RenderEngine/Mesh.h"
-#include "RenderEngine/Texture.h"
#include "SurfaceFlinger.h"
#include <gui/ISurfaceComposerClient.h>
#include <gui/LayerState.h>
-
+#include <renderengine/Mesh.h>
+#include <renderengine/Texture.h>
#include <ui/FrameStats.h>
#include <ui/GraphicBuffer.h>
#include <ui/PixelFormat.h>
diff --git a/services/surfaceflinger/BufferLayerConsumer.cpp b/services/surfaceflinger/BufferLayerConsumer.cpp
index 9096d4c..aa8f4e1 100644
--- a/services/surfaceflinger/BufferLayerConsumer.cpp
+++ b/services/surfaceflinger/BufferLayerConsumer.cpp
@@ -20,10 +20,7 @@
//#define LOG_NDEBUG 0
#include "BufferLayerConsumer.h"
-
#include "Layer.h"
-#include "RenderEngine/Image.h"
-#include "RenderEngine/RenderEngine.h"
#include "Scheduler/DispSync.h"
#include <inttypes.h>
@@ -38,9 +35,9 @@
#include <gui/GLConsumer.h>
#include <gui/ISurfaceComposer.h>
#include <gui/SurfaceComposerClient.h>
-
#include <private/gui/ComposerService.h>
-
+#include <renderengine/Image.h>
+#include <renderengine/RenderEngine.h>
#include <utils/Log.h>
#include <utils/String8.h>
#include <utils/Trace.h>
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index 6dd29ba..dc908d2 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -353,6 +353,9 @@
getBE().compositionInfo.mBuffer->handle, to_string(error).c_str(),
static_cast<int32_t>(error));
}
+ getBE().compositionInfo.mBufferSlot = mActiveBufferSlot;
+ getBE().compositionInfo.mBuffer = mActiveBuffer;
+ getBE().compositionInfo.hwc.fence = acquireFence;
}
// -----------------------------------------------------------------------
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 369ad89..da9dcfb 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -20,9 +20,9 @@
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
#include "BufferStateLayer.h"
-#include "RenderEngine/Image.h"
#include <private/gui/SyncFeatures.h>
+#include <renderengine/Image.h>
namespace android {
diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h
index e492375..038eb01 100644
--- a/services/surfaceflinger/BufferStateLayer.h
+++ b/services/surfaceflinger/BufferStateLayer.h
@@ -16,13 +16,12 @@
#pragma once
-#include "RenderEngine/Image.h"
-#include "RenderEngine/RenderEngine.h"
-
#include "BufferLayer.h"
#include "Layer.h"
#include <gui/GLConsumer.h>
+#include <renderengine/Image.h>
+#include <renderengine/RenderEngine.h>
#include <system/window.h>
#include <utils/String8.h>
diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp
index 7eeaabb..c29698b 100644
--- a/services/surfaceflinger/ColorLayer.cpp
+++ b/services/surfaceflinger/ColorLayer.cpp
@@ -22,14 +22,13 @@
#include <stdlib.h>
#include <sys/types.h>
+#include <renderengine/RenderEngine.h>
+#include <ui/GraphicBuffer.h>
#include <utils/Errors.h>
#include <utils/Log.h>
-#include <ui/GraphicBuffer.h>
-
#include "ColorLayer.h"
#include "DisplayDevice.h"
-#include "RenderEngine/RenderEngine.h"
#include "SurfaceFlinger.h"
namespace android {
@@ -89,6 +88,7 @@
to_string(error).c_str(), static_cast<int32_t>(error));
visible.dump(LOG_TAG);
}
+ getBE().compositionInfo.hwc.visibleRegion = visible;
setCompositionType(displayId, HWC2::Composition::SolidColor);
@@ -97,6 +97,7 @@
ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), mCurrentDataSpace,
to_string(error).c_str(), static_cast<int32_t>(error));
}
+ getBE().compositionInfo.hwc.dataspace = mCurrentDataSpace;
half4 color = getColor();
error = hwcLayer->setColor({static_cast<uint8_t>(std::round(255.0f * color.r)),
@@ -106,6 +107,9 @@
ALOGE("[%s] Failed to set color: %s (%d)", mName.string(), to_string(error).c_str(),
static_cast<int32_t>(error));
}
+ getBE().compositionInfo.hwc.color = { static_cast<uint8_t>(std::round(255.0f * color.r)),
+ static_cast<uint8_t>(std::round(255.0f * color.g)),
+ static_cast<uint8_t>(std::round(255.0f * color.b)), 255 };
// Clear out the transform, because it doesn't make sense absent a source buffer
error = hwcLayer->setTransform(HWC2::Transform::None);
@@ -113,6 +117,7 @@
ALOGE("[%s] Failed to clear transform: %s (%d)", mName.string(), to_string(error).c_str(),
static_cast<int32_t>(error));
}
+ getBE().compositionInfo.hwc.transform = HWC2::Transform::None;
}
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 776b84a..0fbd459 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -18,6 +18,8 @@
#undef LOG_TAG
#define LOG_TAG "DisplayDevice"
+#include "DisplayDevice.h"
+
#include <array>
#include <unordered_set>
@@ -26,31 +28,24 @@
#include <string.h>
#include <math.h>
+#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
+#include <configstore/Utils.h>
#include <cutils/properties.h>
-
-#include <utils/RefBase.h>
-#include <utils/Log.h>
-
+#include <gui/Surface.h>
+#include <hardware/gralloc.h>
+#include <renderengine/RenderEngine.h>
#include <ui/DebugUtils.h>
#include <ui/DisplayInfo.h>
#include <ui/PixelFormat.h>
-
-#include <gui/Surface.h>
-
-#include <hardware/gralloc.h>
+#include <utils/RefBase.h>
+#include <utils/Log.h>
#include "DisplayHardware/DisplaySurface.h"
#include "DisplayHardware/HWComposer.h"
#include "DisplayHardware/HWC2.h"
-#include "RenderEngine/RenderEngine.h"
-
-#include "DisplayDevice.h"
#include "SurfaceFlinger.h"
#include "Layer.h"
-#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
-#include <configstore/Utils.h>
-
namespace android {
// retrieve triple buffer setting from configstore
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index bcb2976..4290988 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -25,8 +25,8 @@
#include <binder/IBinder.h>
#include <hardware/hwcomposer_defs.h>
-#include <gui/ISurfaceComposer.h>
#include <math/mat4.h>
+#include <renderengine/Surface.h>
#include <ui/GraphicTypes.h>
#include <ui/HdrCapabilities.h>
#include <ui/Region.h>
@@ -37,7 +37,6 @@
#include <utils/Timers.h>
#include "RenderArea.h"
-#include "RenderEngine/Surface.h"
struct ANativeWindow;
@@ -334,12 +333,12 @@
class DisplayRenderArea : public RenderArea {
public:
DisplayRenderArea(const sp<const DisplayDevice> device,
- ISurfaceComposer::Rotation rotation = ISurfaceComposer::eRotateNone)
- : DisplayRenderArea(device, device->getBounds(), device->getHeight(), device->getWidth(),
+ ui::Transform::orientation_flags rotation = ui::Transform::ROT_0)
+ : DisplayRenderArea(device, device->getBounds(), device->getWidth(), device->getHeight(),
rotation) {}
- DisplayRenderArea(const sp<const DisplayDevice> device, Rect sourceCrop, uint32_t reqHeight,
- uint32_t reqWidth, ISurfaceComposer::Rotation rotation)
- : RenderArea(reqHeight, reqWidth, CaptureFill::OPAQUE, rotation), mDevice(device),
+ DisplayRenderArea(const sp<const DisplayDevice> device, Rect sourceCrop, uint32_t reqWidth,
+ uint32_t reqHeight, ui::Transform::orientation_flags rotation)
+ : RenderArea(reqWidth, reqHeight, CaptureFill::OPAQUE, rotation), mDevice(device),
mSourceCrop(sourceCrop) {}
const ui::Transform& getTransform() const override { return mDevice->getTransform(); }
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index ef31908..a32ff6e 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -184,6 +184,7 @@
auto newDisplay = std::make_unique<Display>(
*mComposer.get(), mPowerAdvisor, mCapabilities, displayId, displayType);
+ newDisplay->setFrequencyScaleParameters(mFrequencyScaler);
newDisplay->setConnected(true);
mDisplays.emplace(displayId, std::move(newDisplay));
} else if (connection == Connection::Disconnected) {
@@ -223,6 +224,14 @@
return static_cast<Error>(mComposer->executeCommands());
}
+void Device::setDisplayFrequencyScaleParameters(Device::FrequencyScaler frequencyScaler) {
+ mFrequencyScaler = frequencyScaler;
+}
+
+Device::FrequencyScaler Device::getDisplayFrequencyScaleParameters() {
+ return mFrequencyScaler;
+}
+
// Display methods
Display::Display(android::Hwc2::Composer& composer, android::Hwc2::PowerAdvisor& advisor,
@@ -262,6 +271,7 @@
mWidth(-1),
mHeight(-1),
mVsyncPeriod(-1),
+ mFrequencyScaler(display.mFrequencyScaler),
mDpiX(-1),
mDpiY(-1) {}
@@ -701,6 +711,10 @@
mIsConnected = connected;
}
+void Display::setFrequencyScaleParameters(Device::FrequencyScaler frequencyScaler) {
+ mFrequencyScaler = frequencyScaler;
+}
+
int32_t Display::getAttribute(hwc2_config_t configId, Attribute attribute)
{
int32_t value = 0;
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index e0d6ecc..a8f24d6 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -85,6 +85,11 @@
public:
explicit Device(std::unique_ptr<android::Hwc2::Composer> composer);
+ struct FrequencyScaler {
+ int32_t multiplier = 1;
+ int32_t divisor = 1;
+ };
+
void registerCallback(ComposerCallback* callback, int32_t sequenceId);
// Required by HWC2
@@ -116,6 +121,9 @@
// This method provides an explicit way to flush state changes to HWC.
Error flushCommands();
+ void setDisplayFrequencyScaleParameters(FrequencyScaler frequecyScaler);
+ FrequencyScaler getDisplayFrequencyScaleParameters();
+
private:
// Initialization methods
@@ -126,6 +134,7 @@
std::unordered_set<Capability> mCapabilities;
std::unordered_map<hwc2_display_t, std::unique_ptr<Display>> mDisplays;
android::Hwc2::impl::PowerAdvisor mPowerAdvisor;
+ FrequencyScaler mFrequencyScaler;
bool mRegisteredCallback = false;
};
@@ -161,8 +170,6 @@
}
Builder& setVsyncPeriod(int32_t vsyncPeriod) {
mConfig->mVsyncPeriod = vsyncPeriod;
- mConfig->mPeriodMultiplier = 1;
- mConfig->mPeriodDivisor = 1;
return *this;
}
Builder& setDpiX(int32_t dpiX) {
@@ -193,11 +200,7 @@
int32_t getWidth() const { return mWidth; }
int32_t getHeight() const { return mHeight; }
nsecs_t getVsyncPeriod() const {
- return mVsyncPeriod * mPeriodMultiplier / mPeriodDivisor; }
- void scalePanelFrequency(int32_t multiplier, int32_t divisor) const {
- mPeriodMultiplier = multiplier;
- mPeriodDivisor = divisor;
- }
+ return mVsyncPeriod * mFrequencyScaler.multiplier / mFrequencyScaler.divisor; }
float getDpiX() const { return mDpiX; }
float getDpiY() const { return mDpiY; }
@@ -210,8 +213,7 @@
int32_t mWidth;
int32_t mHeight;
nsecs_t mVsyncPeriod;
- mutable int32_t mPeriodMultiplier;
- mutable int32_t mPeriodDivisor;
+ Device::FrequencyScaler mFrequencyScaler;
float mDpiX;
float mDpiY;
};
@@ -279,6 +281,7 @@
hwc2_display_t getId() const { return mId; }
bool isConnected() const { return mIsConnected; }
void setConnected(bool connected); // For use by Device only
+ void setFrequencyScaleParameters(Device::FrequencyScaler frequencyScaler);
private:
int32_t getAttribute(hwc2_config_t configId, Attribute attribute);
@@ -303,6 +306,7 @@
hwc2_display_t mId;
bool mIsConnected;
DisplayType mType;
+ Device::FrequencyScaler mFrequencyScaler;
std::unordered_map<hwc2_layer_t, std::unique_ptr<Layer>> mLayers;
std::unordered_map<hwc2_config_t, std::shared_ptr<const Config>> mConfigs;
};
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index bf8905a..630cc0b 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -807,4 +807,15 @@
return mDisplayData[displayId].hwcDisplay->getId();
}
+void HWComposer::setDisplayFrequencyScaleParameters(
+ HWC2::Device::FrequencyScaler frequencyScaler)
+{
+ mHwcDevice->setDisplayFrequencyScaleParameters(frequencyScaler);
+}
+
+HWC2::Device::FrequencyScaler HWComposer::getDisplayFrequencyScaleParameters()
+{
+ return mHwcDevice->getDisplayFrequencyScaleParameters();
+}
+
} // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 3c5efea..9e01626 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -184,6 +184,14 @@
android::Hwc2::Composer* getComposer() const { return mHwcDevice->getComposer(); }
std::optional<hwc2_display_t> getHwcDisplayId(int32_t displayId) const;
+
+ // ------------------------------------------------------------------------
+ // These functions set and get the frequencyScaler. The frequencyScaler holds
+ // a multiplier and divisor for virtually scaling the panel frequency in
+ // software. This is used to simulate different panel frequencies when
+ // panel hardware is not available.
+ void setDisplayFrequencyScaleParameters(HWC2::Device::FrequencyScaler frequencyScaler);
+ HWC2::Device::FrequencyScaler getDisplayFrequencyScaleParameters();
private:
// For unit tests
friend TestableSurfaceFlinger;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 04beae0..68b5a31 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -53,7 +53,7 @@
#include "DisplayHardware/HWComposer.h"
-#include "RenderEngine/RenderEngine.h"
+#include <renderengine/RenderEngine.h>
#include <mutex>
#include "LayerProtoHelper.h"
@@ -516,6 +516,7 @@
" %s (%d)",
mName.string(), to_string(blendMode).c_str(), to_string(error).c_str(),
static_cast<int32_t>(error));
+ getBE().compositionInfo.hwc.blendMode = blendMode;
// apply the layer's transform, followed by the display's global transform
// here we're guaranteed that the layer's transform preserves rects
@@ -568,6 +569,7 @@
} else {
hwcInfo.displayFrame = transformedFrame;
}
+ getBE().compositionInfo.hwc.displayFrame = transformedFrame;
FloatRect sourceCrop = computeCrop(display);
error = hwcLayer->setSourceCrop(sourceCrop);
@@ -579,6 +581,7 @@
} else {
hwcInfo.sourceCrop = sourceCrop;
}
+ getBE().compositionInfo.hwc.sourceCrop = sourceCrop;
float alpha = static_cast<float>(getAlpha());
error = hwcLayer->setPlaneAlpha(alpha);
@@ -586,10 +589,12 @@
"[%s] Failed to set plane alpha %.3f: "
"%s (%d)",
mName.string(), alpha, to_string(error).c_str(), static_cast<int32_t>(error));
+ getBE().compositionInfo.hwc.alpha = alpha;
error = hwcLayer->setZOrder(z);
ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set Z %u: %s (%d)", mName.string(), z,
to_string(error).c_str(), static_cast<int32_t>(error));
+ getBE().compositionInfo.hwc.z = z;
int type = s.type;
int appId = s.appId;
@@ -606,6 +611,9 @@
ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set info (%d)", mName.string(),
static_cast<int32_t>(error));
+ getBE().compositionInfo.hwc.type = type;
+ getBE().compositionInfo.hwc.appId = appId;
+
/*
* Transformations are applied in this order:
* 1) buffer orientation/flip/mirror
@@ -642,6 +650,7 @@
if (orientation & ui::Transform::ROT_INVALID) {
// we can only handle simple transformation
hwcInfo.forceClientComposition = true;
+ getBE().mHwcLayers[displayId].compositionType = HWC2::Composition::Client;
} else {
auto transform = static_cast<HWC2::Transform>(orientation);
hwcInfo.transform = transform;
@@ -651,6 +660,7 @@
"%s (%d)",
mName.string(), to_string(transform).c_str(), to_string(error).c_str(),
static_cast<int32_t>(error));
+ getBE().compositionInfo.hwc.transform = transform;
}
}
@@ -762,16 +772,12 @@
}
HWC2::Composition Layer::getCompositionType(int32_t displayId) const {
- if (displayId == DisplayDevice::DISPLAY_ID_INVALID) {
+ if (getBE().mHwcLayers.count(displayId) == 0) {
// If we're querying the composition type for a display that does not
// have a HWC counterpart, then it will always be Client
return HWC2::Composition::Client;
}
- if (getBE().mHwcLayers.count(displayId) == 0) {
- ALOGE("getCompositionType called with an invalid HWC layer");
- return HWC2::Composition::Invalid;
- }
- return getBE().mHwcLayers.at(displayId).compositionType;
+ return getBE().mHwcLayers[displayId].compositionType;
}
void Layer::setClearClientTarget(int32_t displayId, bool clear) {
@@ -1527,6 +1533,12 @@
const FloatRect& crop = hwcInfo.sourceCrop;
result.appendFormat("%6.1f %6.1f %6.1f %6.1f\n", crop.left, crop.top, crop.right, crop.bottom);
+ result.append("- - - - - - - - - - - - - - - -\n");
+
+ std::string compositionInfoStr;
+ getBE().compositionInfo.dump(compositionInfoStr, "compositionInfo");
+ result.append(compositionInfoStr.c_str());
+
result.append("- - - - - - - - - - - - - - - -");
result.append("- - - - - - - - - - - - - - - -");
result.append("- - - - - - - - - - - - - - -\n");
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 6ebd668..443f410 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -19,23 +19,26 @@
#include <sys/types.h>
-#include <utils/RefBase.h>
-#include <utils/String8.h>
-#include <utils/Timers.h>
-
+#include <gui/BufferQueue.h>
+#include <gui/ISurfaceComposerClient.h>
+#include <gui/LayerState.h>
+#include <layerproto/LayerProtoHeader.h>
+#include <math/vec4.h>
+#include <renderengine/Mesh.h>
+#include <renderengine/Texture.h>
#include <ui/FloatRect.h>
#include <ui/FrameStats.h>
#include <ui/GraphicBuffer.h>
#include <ui/PixelFormat.h>
#include <ui/Region.h>
#include <ui/Transform.h>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+#include <utils/Timers.h>
-#include <gui/BufferQueue.h>
-#include <gui/ISurfaceComposerClient.h>
-#include <gui/LayerState.h>
-
-#include <list>
#include <cstdint>
+#include <list>
+#include <vector>
#include "Client.h"
#include "FrameTracker.h"
@@ -45,15 +48,9 @@
#include "SurfaceFlinger.h"
#include "TimeStats/TimeStats.h"
-#include <layerproto/LayerProtoHeader.h>
#include "DisplayHardware/HWComposer.h"
#include "DisplayHardware/HWComposerBufferCache.h"
#include "RenderArea.h"
-#include "RenderEngine/Mesh.h"
-#include "RenderEngine/Texture.h"
-
-#include <math/vec4.h>
-#include <vector>
using namespace android::surfaceflinger;
@@ -513,6 +510,14 @@
return getBE().mHwcLayers[displayId].layer.get();
}
+ bool setHwcLayer(int32_t hwcId) {
+ if (getBE().mHwcLayers.count(hwcId) == 0) {
+ return false;
+ }
+ getBE().compositionInfo.hwc.hwcLayer = getBE().mHwcLayers[hwcId].layer;
+ return true;
+ }
+
// -----------------------------------------------------------------------
void clearWithOpenGL(const RenderArea& renderArea) const;
diff --git a/services/surfaceflinger/LayerBE.cpp b/services/surfaceflinger/LayerBE.cpp
index b936b3f..3e04f26 100644
--- a/services/surfaceflinger/LayerBE.cpp
+++ b/services/surfaceflinger/LayerBE.cpp
@@ -21,6 +21,11 @@
#include "Layer.h"
+#include <android-base/stringprintf.h>
+#include <renderengine/RenderEngine.h>
+
+#include <string>
+
namespace android {
LayerBE::LayerBE(Layer* layer, std::string layerName)
@@ -41,50 +46,94 @@
mLayer->onLayerDisplayed(releaseFence);
}
-void CompositionInfo::dumpHwc(const char* tag) const {
- ALOGV("[%s]\thwcLayer=%p", tag, hwc.hwcLayer.get());
- ALOGV("[%s]\tfence=%p", tag, hwc.fence.get());
- ALOGV("[%s]\ttransform=%d", tag, hwc.transform);
- ALOGV("[%s]\tz=%d", tag, hwc.z);
- ALOGV("[%s]\ttype=%d", tag, hwc.type);
- ALOGV("[%s]\tappId=%d", tag, hwc.appId);
- ALOGV("[%s]\tdisplayFrame=%4d %4d %4d %4d", tag, hwc.displayFrame.left, hwc.displayFrame.top, hwc.displayFrame.right, hwc.displayFrame.bottom);
- ALOGV("[%s]\talpha=%.3f", tag, hwc.alpha);
- ALOGV("[%s]\tsourceCrop=%6.1f %6.1f %6.1f %6.1f", tag, hwc.sourceCrop.left, hwc.sourceCrop.top, hwc.sourceCrop.right, hwc.sourceCrop.bottom);
-
- std::string label = tag;
- label+=":visibleRegion";
- hwc.visibleRegion.dump(label.c_str());
- label = tag;
- label+=":surfaceDamage";
- hwc.surfaceDamage.dump(label.c_str());
+void CompositionInfo::dump(const char* tag) const
+{
+ std::string logString;
+ dump(logString, tag);
+ ALOGV("%s", logString.c_str());
}
-void CompositionInfo::dumpRe(const char* tag) const {
- ALOGV("[%s]\tblackoutLayer=%d", tag, re.blackoutLayer);
- ALOGV("[%s]\tclearArea=%d", tag, re.clearArea);
- ALOGV("[%s]\tpreMultipliedAlpha=%d", tag, re.preMultipliedAlpha);
- ALOGV("[%s]\topaque=%d", tag, re.opaque);
- ALOGV("[%s]\tdisableTexture=%d", tag, re.disableTexture);
- ALOGV("[%s]\ttexture:name(%d), target(%d), size(%d/%d)", tag, re.texture.getTextureName(), re.texture.getTextureTarget(), (unsigned int)re.texture.getWidth(), (unsigned int)re.texture.getHeight());
- ALOGV("[%s]\tuseIdentityTransform=%d\n", tag, re.useIdentityTransform);
+void CompositionInfo::dumpHwc(std::string& result, const char* tag) const {
+ if (tag == nullptr) {
+ result += base::StringPrintf("HWC parameters\n");
+ } else {
+ result += base::StringPrintf("[%s]HWC parameters\n", tag);
+ }
+
+ result += base::StringPrintf("\thwcLayer=%p\n", static_cast<HWC2::Layer*>(&*hwc.hwcLayer));
+ result += base::StringPrintf("\tfence=%p\n", hwc.fence.get());
+ result += base::StringPrintf("\tblendMode=%d\n", hwc.blendMode);
+ result += base::StringPrintf("\ttransform=%d\n", hwc.transform);
+ result += base::StringPrintf("\tz=%d\n", hwc.z);
+ result += base::StringPrintf("\ttype=%d\n", hwc.type);
+ result += base::StringPrintf("\tappId=%d\n", hwc.appId);
+ result += base::StringPrintf("\tdisplayFrame=%4d %4d %4d %4d\n", hwc.displayFrame.left, hwc.displayFrame.top, hwc.displayFrame.right, hwc.displayFrame.bottom);
+ result += base::StringPrintf("\talpha=%.3f", hwc.alpha);
+ result += base::StringPrintf("\tsourceCrop=%6.1f %6.1f %6.1f %6.1f\n", hwc.sourceCrop.left, hwc.sourceCrop.top, hwc.sourceCrop.right, hwc.sourceCrop.bottom);
+
+ {
+ //
+ // Keep a conversion from std::string to String8 and back until Region can use std::string
+ //
+ String8 regionString;
+ hwc.visibleRegion.dump(regionString, "visibleRegion");
+ hwc.surfaceDamage.dump(regionString, "surfaceDamage");
+ result += regionString.string();
+ }
}
-void CompositionInfo::dump(const char* tag) const {
- ALOGV("[%s] CompositionInfo", tag);
- ALOGV("[%s]\tLayerName: %s", tag, layerName.c_str());
- ALOGV("[%s]\tCompositionType: %d", tag, compositionType);
- ALOGV("[%s]\tmBuffer = %p", tag, mBuffer.get());
- ALOGV("[%s]\tmBufferSlot=%d", tag, mBufferSlot);
+void CompositionInfo::dumpRe(std::string& result, const char* tag) const {
+ if (tag == nullptr) {
+ result += base::StringPrintf("RenderEngine parameters:\n");
+ } else {
+ result += base::StringPrintf("[%s]RenderEngine parameters:\n", tag);
+ }
+
+ Mesh& mesh = layer->getMesh();
+ result += base::StringPrintf("\tblackoutLayer=%d\n", re.blackoutLayer);
+ result += base::StringPrintf("\tclearArea=%d\n", re.clearArea);
+ result += base::StringPrintf("\tpreMultipliedAlpha=%d\n", re.preMultipliedAlpha);
+ result += base::StringPrintf("\topaque=%d\n", re.opaque);
+ result += base::StringPrintf("\tdisableTexture=%d\n", re.disableTexture);
+ result += base::StringPrintf("\ttexture:name(%d), target(%d), size(%d/%d)\n", re.texture.getTextureName(), re.texture.getTextureTarget(), (unsigned int)re.texture.getWidth(), (unsigned int)re.texture.getHeight());
+ result += base::StringPrintf("\tuseIdentityTransform=%d\n", re.useIdentityTransform);
+ Mesh::VertexArray<vec2> positions(mesh.getPositionArray<vec2>());
+ result += base::StringPrintf("\tpositions[(%6.1f,%6.1f), (%6.1f,%6.1f), (%6.1f,%6.1f), (%6.1f,%6.1f)]\n",
+ positions[0][0], positions[0][1], positions[1][0], positions[1][1],
+ positions[2][0], positions[2][1], positions[3][0], positions[3][1]);
+ Mesh::VertexArray<vec2> texCoords(mesh.getTexCoordArray<vec2>());
+ result += base::StringPrintf("\ttexCoords[(%6.1f,%6.1f), (%6.1f,%6.1f),(%6.1f,%6.1f),(%6.1f,%6.1f)]\n",
+ texCoords[0][0], texCoords[0][1], texCoords[1][0], texCoords[1][1],
+ texCoords[2][0], texCoords[2][1], texCoords[3][0], texCoords[3][1]);
+}
+
+void CompositionInfo::dump(std::string& result, const char* tag) const
+{
+ if (tag == nullptr) {
+ result += base::StringPrintf("CompositionInfo\n");
+ } else {
+ result += base::StringPrintf("[%s]CompositionInfo\n", tag);
+ }
+ result += base::StringPrintf("\tLayerName: %s\n", layerName.c_str());
+ result += base::StringPrintf("\tCompositionType: %d\n", compositionType);
+ result += base::StringPrintf("\tmBuffer = %p\n", mBuffer.get());
+ result += base::StringPrintf("\tmBufferSlot=%d\n", mBufferSlot);
+ result += base::StringPrintf("\tdisplayFrame=%4d %4d %4d %4d\n", hwc.displayFrame.left, hwc.displayFrame.top, hwc.displayFrame.right, hwc.displayFrame.bottom);
+ result += base::StringPrintf("\talpha=%f\n", hwc.alpha);
+ result += base::StringPrintf("\tsourceCrop=%6.1f %6.1f %6.1f %6.1f\n", hwc.sourceCrop.left, hwc.sourceCrop.top, hwc.sourceCrop.right, hwc.sourceCrop.bottom);
+
switch (compositionType) {
case HWC2::Composition::Device:
- dumpHwc(tag);
+ dumpHwc(result, tag);
break;
case HWC2::Composition::Client:
- dumpRe(tag);
+ dumpRe(result, tag);
+ break;
default:
break;
}
}
+
+
}; // namespace android
diff --git a/services/surfaceflinger/LayerBE.h b/services/surfaceflinger/LayerBE.h
index 3055621..e5110b7 100644
--- a/services/surfaceflinger/LayerBE.h
+++ b/services/surfaceflinger/LayerBE.h
@@ -19,14 +19,13 @@
#include <stdint.h>
#include <sys/types.h>
+#include <renderengine/Mesh.h>
+#include <renderengine/Texture.h>
#include <ui/Region.h>
-#include "SurfaceFlinger.h"
-
#include "DisplayHardware/HWComposer.h"
#include "DisplayHardware/HWComposerBufferCache.h"
-#include "RenderEngine/Mesh.h"
-#include "RenderEngine/Texture.h"
+#include "SurfaceFlinger.h"
namespace android {
@@ -40,6 +39,7 @@
std::shared_ptr<LayerBE> layer;
struct {
std::shared_ptr<HWC2::Layer> hwcLayer;
+ int32_t displayId = -1;
sp<Fence> fence;
HWC2::BlendMode blendMode = HWC2::BlendMode::Invalid;
Rect displayFrame;
@@ -55,6 +55,8 @@
ui::Dataspace dataspace;
hwc_color_t color;
bool clearClientTarget = false;
+ bool supportedPerFrameMetadata = false;
+ HdrMetadata hdrMetadata;
} hwc;
struct {
Mesh* mesh;
@@ -70,8 +72,9 @@
} re;
void dump(const char* tag) const;
- void dumpHwc(const char* tag) const;
- void dumpRe(const char* tag) const;
+ void dump(std::string& result, const char* tag = nullptr) const;
+ void dumpHwc(std::string& result, const char* tag = nullptr) const;
+ void dumpRe(std::string& result, const char* tag = nullptr) const;
};
class LayerBE {
diff --git a/services/surfaceflinger/RenderArea.cpp b/services/surfaceflinger/RenderArea.cpp
index 7f69ce4..93759e8 100644
--- a/services/surfaceflinger/RenderArea.cpp
+++ b/services/surfaceflinger/RenderArea.cpp
@@ -1,30 +1,7 @@
#include "RenderArea.h"
-#include <gui/LayerState.h>
-
namespace android {
-ui::Transform::orientation_flags fromRotation(ISurfaceComposer::Rotation rotation) {
- switch (rotation) {
- case ISurfaceComposer::eRotateNone:
- return ui::Transform::ROT_0;
- case ISurfaceComposer::eRotate90:
- return ui::Transform::ROT_90;
- case ISurfaceComposer::eRotate180:
- return ui::Transform::ROT_180;
- case ISurfaceComposer::eRotate270:
- return ui::Transform::ROT_270;
- }
- ALOGE("Invalid rotation passed to captureScreen(): %d\n", rotation);
- return ui::Transform::ROT_0;
-}
-
-RenderArea::RenderArea(uint32_t reqHeight, uint32_t reqWidth, CaptureFill captureFill,
- ISurfaceComposer::Rotation rotation)
- : mReqHeight(reqHeight), mReqWidth(reqWidth), mCaptureFill(captureFill) {
- mRotationFlags = fromRotation(rotation);
-}
-
float RenderArea::getCaptureFillValue(CaptureFill captureFill) {
switch(captureFill) {
case CaptureFill::CLEAR:
@@ -34,37 +11,5 @@
return 1.0f;
}
}
-/*
- * Checks that the requested width and height are valid and updates them to the render area
- * dimensions if they are set to 0
- */
-status_t RenderArea::updateDimensions(int displayRotation) {
- // get screen geometry
-
- uint32_t width = getWidth();
- uint32_t height = getHeight();
-
- if (mRotationFlags & ui::Transform::ROT_90) {
- std::swap(width, height);
- }
-
- if (displayRotation & DisplayState::eOrientationSwapMask) {
- std::swap(width, height);
- }
-
- if ((mReqWidth > width) || (mReqHeight > height)) {
- ALOGE("size mismatch (%d, %d) > (%d, %d)", mReqWidth, mReqHeight, width, height);
- return BAD_VALUE;
- }
-
- if (mReqWidth == 0) {
- mReqWidth = width;
- }
- if (mReqHeight == 0) {
- mReqHeight = height;
- }
-
- return NO_ERROR;
-}
} // namespace android
diff --git a/services/surfaceflinger/RenderArea.h b/services/surfaceflinger/RenderArea.h
index e38f462..3c11e73 100644
--- a/services/surfaceflinger/RenderArea.h
+++ b/services/surfaceflinger/RenderArea.h
@@ -1,47 +1,80 @@
#pragma once
-#include <gui/ISurfaceComposer.h>
-#include <ui/GraphicTypes.h>
#include <ui/Transform.h>
#include <functional>
namespace android {
+// RenderArea describes a rectangular area that layers can be rendered to.
+//
+// There is a logical render area and a physical render area. When a layer is
+// rendered to the render area, it is first transformed and clipped to the logical
+// render area. The transformed and clipped layer is then projected onto the
+// physical render area.
class RenderArea {
-
public:
enum class CaptureFill {CLEAR, OPAQUE};
static float getCaptureFillValue(CaptureFill captureFill);
- RenderArea(uint32_t reqHeight, uint32_t reqWidth, CaptureFill captureFill,
- ISurfaceComposer::Rotation rotation = ISurfaceComposer::eRotateNone);
+ RenderArea(uint32_t reqWidth, uint32_t reqHeight, CaptureFill captureFill,
+ ui::Transform::orientation_flags rotation = ui::Transform::ROT_0)
+ : mReqWidth(reqWidth),
+ mReqHeight(reqHeight),
+ mCaptureFill(captureFill),
+ mRotationFlags(rotation) {}
virtual ~RenderArea() = default;
- virtual const ui::Transform& getTransform() const = 0;
- virtual Rect getBounds() const = 0;
- virtual int getHeight() const = 0;
- virtual int getWidth() const = 0;
- virtual bool isSecure() const = 0;
- virtual bool needsFiltering() const = 0;
- virtual Rect getSourceCrop() const = 0;
-
+ // Invoke drawLayers to render layers into the render area.
virtual void render(std::function<void()> drawLayers) { drawLayers(); }
- int getReqHeight() const { return mReqHeight; };
- int getReqWidth() const { return mReqWidth; };
- ui::Transform::orientation_flags getRotationFlags() const { return mRotationFlags; };
- status_t updateDimensions(int displayRotation);
+ // Returns true if the render area is secure. A secure layer should be
+ // blacked out / skipped when rendered to an insecure render area.
+ virtual bool isSecure() const = 0;
+ // Returns true if the otherwise disabled layer filtering should be
+ // enabled when rendering to this render area.
+ virtual bool needsFiltering() const = 0;
+
+ // Returns the transform to be applied on layers to transform them into
+ // the logical render area.
+ virtual const ui::Transform& getTransform() const = 0;
+
+ // Returns the size of the logical render area. Layers are clipped to the
+ // logical render area.
+ virtual int getWidth() const = 0;
+ virtual int getHeight() const = 0;
+ virtual Rect getBounds() const = 0;
+
+ // Returns the source crop of the render area. The source crop defines
+ // how layers are projected from the logical render area onto the physical
+ // render area. It can be larger than the logical render area. It can
+ // also be optionally rotated.
+ //
+ // Layers are first clipped to the source crop (in addition to being
+ // clipped to the logical render area already). The source crop and the
+ // layers are then rotated around the center of the source crop, and
+ // scaled to the physical render area linearly.
+ virtual Rect getSourceCrop() const = 0;
+
+ // Returns the rotation of the source crop and the layers.
+ ui::Transform::orientation_flags getRotationFlags() const { return mRotationFlags; };
+
+ // Returns the size of the physical render area.
+ int getReqWidth() const { return mReqWidth; };
+ int getReqHeight() const { return mReqHeight; };
+
+ // Returns the fill color of the physical render area. Regions not
+ // covered by any rendered layer should be filled with this color.
CaptureFill getCaptureFill() const { return mCaptureFill; };
private:
- uint32_t mReqHeight;
- uint32_t mReqWidth;
- ui::Transform::orientation_flags mRotationFlags;
- CaptureFill mCaptureFill;
+ const uint32_t mReqWidth;
+ const uint32_t mReqHeight;
+ const CaptureFill mCaptureFill;
+ const ui::Transform::orientation_flags mRotationFlags;
};
} // namespace android
diff --git a/services/surfaceflinger/RenderEngine/Android.bp b/services/surfaceflinger/RenderEngine/Android.bp
new file mode 100644
index 0000000..13752f2
--- /dev/null
+++ b/services/surfaceflinger/RenderEngine/Android.bp
@@ -0,0 +1,75 @@
+// TODO(b/112585051) Add to VNDK once moved to libs/
+cc_defaults {
+ name: "renderengine_defaults",
+ cflags: [
+ "-DLOG_TAG=\"RenderEngine\"",
+ "-Wall",
+ "-Werror",
+ "-Wthread-safety",
+ "-Wunused",
+ "-Wunreachable-code",
+ ],
+ cppflags: ["-std=c++1z"],
+}
+
+cc_defaults {
+ name: "librenderengine_defaults",
+ defaults: ["renderengine_defaults"],
+ cflags: [
+ "-DGL_GLEXT_PROTOTYPES",
+ "-DEGL_EGLEXT_PROTOTYPES",
+ ],
+ shared_libs: [
+ "android.hardware.configstore-utils",
+ "android.hardware.configstore@1.0",
+ "android.hardware.configstore@1.1",
+ "android.hardware.configstore@1.2",
+ "libcutils",
+ "libEGL",
+ "libGLESv1_CM",
+ "libGLESv2",
+ "libgui",
+ "liblog",
+ "libui",
+ "libutils",
+ ],
+ local_include_dirs: ["include"],
+ export_include_dirs: ["include"],
+}
+
+filegroup {
+ name: "librenderengine_sources",
+ srcs: [
+ "Description.cpp",
+ "GLES20RenderEngine.cpp",
+ "GLExtensions.cpp",
+ "Image.cpp",
+ "Mesh.cpp",
+ "Program.cpp",
+ "ProgramCache.cpp",
+ "RenderEngine.cpp",
+ "Surface.cpp",
+ "Texture.cpp",
+ ],
+}
+
+cc_library_static {
+ name: "librenderengine",
+ defaults: ["librenderengine_defaults"],
+ double_loadable: true,
+
+ clang: true,
+ cflags: [
+ "-fvisibility=hidden",
+ "-Werror=format",
+ ],
+ cppflags: [
+ "-fwhole-program-vtables", // requires ThinLTO
+ ],
+ srcs: [
+ ":librenderengine_sources",
+ ],
+ lto: {
+ thin: true,
+ },
+}
diff --git a/services/surfaceflinger/RenderEngine/Description.cpp b/services/surfaceflinger/RenderEngine/Description.cpp
index d4a2bb4..d5f2103 100644
--- a/services/surfaceflinger/RenderEngine/Description.cpp
+++ b/services/surfaceflinger/RenderEngine/Description.cpp
@@ -14,13 +14,13 @@
* limitations under the License.
*/
+#include <renderengine/Description.h>
+
#include <stdint.h>
#include <string.h>
#include <utils/TypeHelpers.h>
-#include "Description.h"
-
namespace android {
void Description::setPremultipliedAlpha(bool premultipliedAlpha) {
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
index 2186594..617ba76 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
@@ -19,26 +19,24 @@
#define LOG_TAG "RenderEngine"
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+#include <renderengine/GLES20RenderEngine.h>
+
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
-
+#include <renderengine/Description.h>
+#include <renderengine/Mesh.h>
+#include <renderengine/Program.h>
+#include <renderengine/ProgramCache.h>
+#include <renderengine/Texture.h>
#include <ui/ColorSpace.h>
#include <ui/DebugUtils.h>
#include <ui/Rect.h>
-
#include <utils/String8.h>
#include <utils/Trace.h>
#include <cutils/compiler.h>
#include <math.h>
-#include "Description.h"
-#include "GLES20RenderEngine.h"
-#include "Mesh.h"
-#include "Program.h"
-#include "ProgramCache.h"
-#include "Texture.h"
-
#include <fstream>
#include <sstream>
@@ -114,7 +112,7 @@
: RenderEngine(featureFlags),
mVpWidth(0),
mVpHeight(0),
- mPlatformHasWideColor((featureFlags & WIDE_COLOR_SUPPORT) != 0) {
+ mUseColorManagement(featureFlags & USE_COLOR_MANAGEMENT) {
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims);
@@ -132,7 +130,7 @@
// mColorBlindnessCorrection = M;
- if (mPlatformHasWideColor) {
+ if (mUseColorManagement) {
ColorSpace srgb(ColorSpace::sRGB());
ColorSpace displayP3(ColorSpace::DisplayP3());
ColorSpace bt2020(ColorSpace::BT2020());
@@ -322,8 +320,8 @@
// BT2020 data space, in that case, the output data space is set to be
// BT2020_HLG or BT2020_PQ respectively. In GPU fall back we need
// to respect this and convert non-HDR content to HDR format.
- if (mPlatformHasWideColor) {
- Description wideColorState = mState;
+ if (mUseColorManagement) {
+ Description managedState = mState;
Dataspace inputStandard = static_cast<Dataspace>(mDataSpace & Dataspace::STANDARD_MASK);
Dataspace inputTransfer = static_cast<Dataspace>(mDataSpace & Dataspace::TRANSFER_MASK);
Dataspace outputStandard = static_cast<Dataspace>(mOutputDataSpace &
@@ -336,26 +334,26 @@
// The supported input color spaces are standard RGB, Display P3 and BT2020.
switch (inputStandard) {
case Dataspace::STANDARD_DCI_P3:
- wideColorState.setInputTransformMatrix(mDisplayP3ToXyz);
+ managedState.setInputTransformMatrix(mDisplayP3ToXyz);
break;
case Dataspace::STANDARD_BT2020:
- wideColorState.setInputTransformMatrix(mBt2020ToXyz);
+ managedState.setInputTransformMatrix(mBt2020ToXyz);
break;
default:
- wideColorState.setInputTransformMatrix(mSrgbToXyz);
+ managedState.setInputTransformMatrix(mSrgbToXyz);
break;
}
// The supported output color spaces are BT2020, Display P3 and standard RGB.
switch (outputStandard) {
case Dataspace::STANDARD_BT2020:
- wideColorState.setOutputTransformMatrix(mXyzToBt2020);
+ managedState.setOutputTransformMatrix(mXyzToBt2020);
break;
case Dataspace::STANDARD_DCI_P3:
- wideColorState.setOutputTransformMatrix(mXyzToDisplayP3);
+ managedState.setOutputTransformMatrix(mXyzToDisplayP3);
break;
default:
- wideColorState.setOutputTransformMatrix(mXyzToSrgb);
+ managedState.setOutputTransformMatrix(mXyzToSrgb);
break;
}
} else if (inputStandard != outputStandard) {
@@ -370,9 +368,9 @@
// - sRGB
// - Display P3
if (outputStandard == Dataspace::STANDARD_BT709) {
- wideColorState.setOutputTransformMatrix(mDisplayP3ToSrgb);
+ managedState.setOutputTransformMatrix(mDisplayP3ToSrgb);
} else if (outputStandard == Dataspace::STANDARD_DCI_P3) {
- wideColorState.setOutputTransformMatrix(mSrgbToDisplayP3);
+ managedState.setOutputTransformMatrix(mSrgbToDisplayP3);
}
}
@@ -380,44 +378,44 @@
// - there is a color matrix that is not an identity matrix, or
// - there is an output transform matrix that is not an identity matrix, or
// - the input transfer function doesn't match the output transfer function.
- if (wideColorState.hasColorMatrix() || wideColorState.hasOutputTransformMatrix() ||
+ if (managedState.hasColorMatrix() || managedState.hasOutputTransformMatrix() ||
inputTransfer != outputTransfer) {
switch (inputTransfer) {
case Dataspace::TRANSFER_ST2084:
- wideColorState.setInputTransferFunction(Description::TransferFunction::ST2084);
+ managedState.setInputTransferFunction(Description::TransferFunction::ST2084);
break;
case Dataspace::TRANSFER_HLG:
- wideColorState.setInputTransferFunction(Description::TransferFunction::HLG);
+ managedState.setInputTransferFunction(Description::TransferFunction::HLG);
break;
case Dataspace::TRANSFER_LINEAR:
- wideColorState.setInputTransferFunction(Description::TransferFunction::LINEAR);
+ managedState.setInputTransferFunction(Description::TransferFunction::LINEAR);
break;
default:
- wideColorState.setInputTransferFunction(Description::TransferFunction::SRGB);
+ managedState.setInputTransferFunction(Description::TransferFunction::SRGB);
break;
}
switch (outputTransfer) {
case Dataspace::TRANSFER_ST2084:
- wideColorState.setOutputTransferFunction(Description::TransferFunction::ST2084);
+ managedState.setOutputTransferFunction(Description::TransferFunction::ST2084);
break;
case Dataspace::TRANSFER_HLG:
- wideColorState.setOutputTransferFunction(Description::TransferFunction::HLG);
+ managedState.setOutputTransferFunction(Description::TransferFunction::HLG);
break;
default:
- wideColorState.setOutputTransferFunction(Description::TransferFunction::SRGB);
+ managedState.setOutputTransferFunction(Description::TransferFunction::SRGB);
break;
}
}
- ProgramCache::getInstance().useProgram(wideColorState);
+ ProgramCache::getInstance().useProgram(managedState);
glDrawArrays(mesh.getPrimitive(), 0, mesh.getVertexCount());
if (outputDebugPPMs) {
- static uint64_t wideColorFrameCount = 0;
+ static uint64_t managedColorFrameCount = 0;
std::ostringstream out;
- out << "/data/texture_out" << wideColorFrameCount++;
+ out << "/data/texture_out" << managedColorFrameCount++;
writePPM(out.str().c_str(), mVpWidth, mVpHeight);
}
} else {
diff --git a/services/surfaceflinger/RenderEngine/GLExtensions.cpp b/services/surfaceflinger/RenderEngine/GLExtensions.cpp
index 23480b4..b4fb2a1 100644
--- a/services/surfaceflinger/RenderEngine/GLExtensions.cpp
+++ b/services/surfaceflinger/RenderEngine/GLExtensions.cpp
@@ -14,12 +14,12 @@
* limitations under the License.
*/
+#include <renderengine/GLExtensions.h>
+
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
-#include "GLExtensions.h"
-
namespace android {
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/RenderEngine/Image.cpp b/services/surfaceflinger/RenderEngine/Image.cpp
index 6e0a880..ee140eb 100644
--- a/services/surfaceflinger/RenderEngine/Image.cpp
+++ b/services/surfaceflinger/RenderEngine/Image.cpp
@@ -14,14 +14,14 @@
* limitations under the License.
*/
-#include "Image.h"
+#include <renderengine/Image.h>
#include <vector>
#include <log/log.h>
-#include "GLExtensions.h"
-#include "RenderEngine.h"
+#include <renderengine/GLExtensions.h>
+#include <renderengine/RenderEngine.h>
namespace android {
namespace RE {
diff --git a/services/surfaceflinger/RenderEngine/Mesh.cpp b/services/surfaceflinger/RenderEngine/Mesh.cpp
index 6a62b1d..43852eb 100644
--- a/services/surfaceflinger/RenderEngine/Mesh.cpp
+++ b/services/surfaceflinger/RenderEngine/Mesh.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "Mesh.h"
+#include <renderengine/Mesh.h>
#include <utils/Log.h>
diff --git a/services/surfaceflinger/RenderEngine/Program.cpp b/services/surfaceflinger/RenderEngine/Program.cpp
index fe536f0..87371dc 100644
--- a/services/surfaceflinger/RenderEngine/Program.cpp
+++ b/services/surfaceflinger/RenderEngine/Program.cpp
@@ -14,15 +14,15 @@
* limitations under the License.
*/
+#include <renderengine/Program.h>
+
#include <stdint.h>
#include <log/log.h>
-#include <utils/String8.h>
-
#include <math/mat4.h>
-#include "Description.h"
-#include "Program.h"
-#include "ProgramCache.h"
+#include <renderengine/Description.h>
+#include <renderengine/ProgramCache.h>
+#include <utils/String8.h>
namespace android {
diff --git a/services/surfaceflinger/RenderEngine/ProgramCache.cpp b/services/surfaceflinger/RenderEngine/ProgramCache.cpp
index 9dc6858..b7101e0 100644
--- a/services/surfaceflinger/RenderEngine/ProgramCache.cpp
+++ b/services/surfaceflinger/RenderEngine/ProgramCache.cpp
@@ -16,16 +16,15 @@
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+#include <renderengine/ProgramCache.h>
+
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
-
+#include <renderengine/Description.h>
+#include <renderengine/Program.h>
#include <utils/String8.h>
#include <utils/Trace.h>
-#include "Description.h"
-#include "Program.h"
-#include "ProgramCache.h"
-
namespace android {
// -----------------------------------------------------------------------------------------------
@@ -82,7 +81,7 @@
ProgramCache::~ProgramCache() {}
-void ProgramCache::primeCache(bool hasWideColor) {
+void ProgramCache::primeCache(bool useColorManagement) {
uint32_t shaderCount = 0;
uint32_t keyMask = Key::BLEND_MASK | Key::OPACITY_MASK | Key::ALPHA_MASK | Key::TEXTURE_MASK;
// Prime the cache for all combinations of the above masks,
@@ -105,7 +104,7 @@
}
// Prime for sRGB->P3 conversion
- if (hasWideColor) {
+ if (useColorManagement) {
Key shaderKey;
shaderKey.set(Key::BLEND_MASK | Key::TEXTURE_MASK | Key::OUTPUT_TRANSFORM_MATRIX_MASK |
Key::INPUT_TF_MASK | Key::OUTPUT_TF_MASK,
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.cpp b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
index 39f7e30..594b1ed 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
@@ -14,22 +14,21 @@
* limitations under the License.
*/
-#include <log/log.h>
-#include <ui/Rect.h>
-#include <ui/Region.h>
-
-#include "GLES20RenderEngine.h"
-#include "GLExtensions.h"
-#include "Image.h"
-#include "Mesh.h"
-#include "RenderEngine.h"
-
-#include <SurfaceFlinger.h>
-#include <vector>
+#include <renderengine/RenderEngine.h>
#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
#include <configstore/Utils.h>
+#include <log/log.h>
#include <private/gui/SyncFeatures.h>
+#include <renderengine/GLES20RenderEngine.h>
+#include <renderengine/GLExtensions.h>
+#include <renderengine/Image.h>
+#include <renderengine/Mesh.h>
+#include <renderengine/Surface.h>
+#include <ui/Rect.h>
+#include <ui/Region.h>
+
+#include <vector>
using namespace android::hardware::configstore;
using namespace android::hardware::configstore::V1_0;
@@ -596,7 +595,7 @@
}
void RenderEngine::primeCache() const {
- ProgramCache::getInstance().primeCache(mFeatureFlags & WIDE_COLOR_SUPPORT);
+ ProgramCache::getInstance().primeCache(mFeatureFlags & USE_COLOR_MANAGEMENT);
}
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/RenderEngine/Surface.cpp b/services/surfaceflinger/RenderEngine/Surface.cpp
index 3bf42fb..3e98ab4 100644
--- a/services/surfaceflinger/RenderEngine/Surface.cpp
+++ b/services/surfaceflinger/RenderEngine/Surface.cpp
@@ -14,11 +14,10 @@
* limitations under the License.
*/
-#include "Surface.h"
-
-#include "RenderEngine.h"
+#include <renderengine/Surface.h>
#include <log/log.h>
+#include <renderengine/RenderEngine.h>
#include <ui/PixelFormat.h>
namespace android {
diff --git a/services/surfaceflinger/RenderEngine/Texture.cpp b/services/surfaceflinger/RenderEngine/Texture.cpp
index 351430f..c07ba08 100644
--- a/services/surfaceflinger/RenderEngine/Texture.cpp
+++ b/services/surfaceflinger/RenderEngine/Texture.cpp
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-#include <string.h>
+#include <renderengine/Texture.h>
-#include "Texture.h"
+#include <string.h>
namespace android {
diff --git a/services/surfaceflinger/RenderEngine/Description.h b/services/surfaceflinger/RenderEngine/include/renderengine/Description.h
similarity index 98%
rename from services/surfaceflinger/RenderEngine/Description.h
rename to services/surfaceflinger/RenderEngine/include/renderengine/Description.h
index 6ebb340..9bc7e1c 100644
--- a/services/surfaceflinger/RenderEngine/Description.h
+++ b/services/surfaceflinger/RenderEngine/include/renderengine/Description.h
@@ -15,7 +15,7 @@
*/
#include <GLES2/gl2.h>
-#include "Texture.h"
+#include <renderengine/Texture.h>
#ifndef SF_RENDER_ENGINE_DESCRIPTION_H_
#define SF_RENDER_ENGINE_DESCRIPTION_H_
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h b/services/surfaceflinger/RenderEngine/include/renderengine/GLES20RenderEngine.h
similarity index 92%
rename from services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
rename to services/surfaceflinger/RenderEngine/include/renderengine/GLES20RenderEngine.h
index f682225..0e9efdb 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/include/renderengine/GLES20RenderEngine.h
@@ -21,10 +21,9 @@
#include <sys/types.h>
#include <GLES2/gl2.h>
-
-#include "Description.h"
-#include "ProgramCache.h"
-#include "RenderEngine.h"
+#include <renderengine/Description.h>
+#include <renderengine/ProgramCache.h>
+#include <renderengine/RenderEngine.h>
// ---------------------------------------------------------------------------
namespace android {
@@ -94,8 +93,9 @@
// Current output dataspace of the render engine
ui::Dataspace mOutputDataSpace = ui::Dataspace::UNKNOWN;
- // Currently only supporting sRGB, BT2020 and DisplayP3 color spaces
- const bool mPlatformHasWideColor = false;
+ // Whether device supports color management, currently color management
+ // supports sRGB, DisplayP3 color spaces.
+ const bool mUseColorManagement = false;
mat4 mSrgbToDisplayP3;
mat4 mDisplayP3ToSrgb;
mat3 mSrgbToXyz;
diff --git a/services/surfaceflinger/RenderEngine/GLExtensions.h b/services/surfaceflinger/RenderEngine/include/renderengine/GLExtensions.h
similarity index 99%
rename from services/surfaceflinger/RenderEngine/GLExtensions.h
rename to services/surfaceflinger/RenderEngine/include/renderengine/GLExtensions.h
index a6a5053..1ff0d24 100644
--- a/services/surfaceflinger/RenderEngine/GLExtensions.h
+++ b/services/surfaceflinger/RenderEngine/include/renderengine/GLExtensions.h
@@ -20,15 +20,15 @@
#include <stdint.h>
#include <sys/types.h>
-#include <utils/Singleton.h>
-#include <utils/SortedVector.h>
-#include <utils/String8.h>
-
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES/gl.h>
#include <GLES/glext.h>
+#include <utils/Singleton.h>
+#include <utils/SortedVector.h>
+#include <utils/String8.h>
+
namespace android {
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/RenderEngine/Image.h b/services/surfaceflinger/RenderEngine/include/renderengine/Image.h
similarity index 100%
rename from services/surfaceflinger/RenderEngine/Image.h
rename to services/surfaceflinger/RenderEngine/include/renderengine/Image.h
diff --git a/services/surfaceflinger/RenderEngine/Mesh.h b/services/surfaceflinger/RenderEngine/include/renderengine/Mesh.h
similarity index 100%
rename from services/surfaceflinger/RenderEngine/Mesh.h
rename to services/surfaceflinger/RenderEngine/include/renderengine/Mesh.h
diff --git a/services/surfaceflinger/RenderEngine/Program.h b/services/surfaceflinger/RenderEngine/include/renderengine/Program.h
similarity index 96%
rename from services/surfaceflinger/RenderEngine/Program.h
rename to services/surfaceflinger/RenderEngine/include/renderengine/Program.h
index ae796c5..5e621cb 100644
--- a/services/surfaceflinger/RenderEngine/Program.h
+++ b/services/surfaceflinger/RenderEngine/include/renderengine/Program.h
@@ -20,9 +20,8 @@
#include <stdint.h>
#include <GLES2/gl2.h>
-
-#include "Description.h"
-#include "ProgramCache.h"
+#include <renderengine/Description.h>
+#include <renderengine/ProgramCache.h>
namespace android {
diff --git a/services/surfaceflinger/RenderEngine/ProgramCache.h b/services/surfaceflinger/RenderEngine/include/renderengine/ProgramCache.h
similarity index 98%
rename from services/surfaceflinger/RenderEngine/ProgramCache.h
rename to services/surfaceflinger/RenderEngine/include/renderengine/ProgramCache.h
index 983e7ba..a5bee45 100644
--- a/services/surfaceflinger/RenderEngine/ProgramCache.h
+++ b/services/surfaceflinger/RenderEngine/include/renderengine/ProgramCache.h
@@ -18,13 +18,11 @@
#define SF_RENDER_ENGINE_PROGRAMCACHE_H
#include <GLES2/gl2.h>
-
+#include <renderengine/Description.h>
#include <utils/KeyedVector.h>
#include <utils/Singleton.h>
#include <utils/TypeHelpers.h>
-#include "Description.h"
-
namespace android {
class Description;
@@ -161,7 +159,7 @@
~ProgramCache();
// Generate shaders to populate the cache
- void primeCache(bool hasWideColor);
+ void primeCache(bool useColorManagement);
// useProgram lookup a suitable program in the cache or generates one
// if none can be found.
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.h b/services/surfaceflinger/RenderEngine/include/renderengine/RenderEngine.h
similarity index 98%
rename from services/surfaceflinger/RenderEngine/RenderEngine.h
rename to services/surfaceflinger/RenderEngine/include/renderengine/RenderEngine.h
index 2ed2cc7..6213784 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/include/renderengine/RenderEngine.h
@@ -56,7 +56,7 @@
class RenderEngine {
public:
enum FeatureFlag {
- WIDE_COLOR_SUPPORT = 1 << 0 // Platform has a wide color display
+ USE_COLOR_MANAGEMENT = 1 << 0, // Device manages color
};
virtual ~RenderEngine() = 0;
diff --git a/services/surfaceflinger/RenderEngine/Surface.h b/services/surfaceflinger/RenderEngine/include/renderengine/Surface.h
similarity index 100%
rename from services/surfaceflinger/RenderEngine/Surface.h
rename to services/surfaceflinger/RenderEngine/include/renderengine/Surface.h
diff --git a/services/surfaceflinger/RenderEngine/Texture.h b/services/surfaceflinger/RenderEngine/include/renderengine/Texture.h
similarity index 100%
rename from services/surfaceflinger/RenderEngine/Texture.h
rename to services/surfaceflinger/RenderEngine/include/renderengine/Texture.h
diff --git a/services/surfaceflinger/Scheduler/DispSync.cpp b/services/surfaceflinger/Scheduler/DispSync.cpp
index 9d9acd3..54a1b51 100644
--- a/services/surfaceflinger/Scheduler/DispSync.cpp
+++ b/services/surfaceflinger/Scheduler/DispSync.cpp
@@ -521,16 +521,18 @@
mThread->updateModel(mPeriod, mPhase, mReferenceTime);
}
-void DispSync::scalePeriod(uint32_t multiplier, uint32_t divisor) {
+void DispSync::scalePeriod(HWC2::Device::FrequencyScaler frequencyScaler) {
Mutex::Autolock lock(mMutex);
// if only 1 of the properties is updated, we will get to this
// point "attempting" to set the scale to 1 when it is already
// 1. Check that special case so that we don't do a useless
// update of the model.
- if ((multiplier == 1) && (divisor == 1) && (mPeriod == mPeriodBase)) return;
+ if ((frequencyScaler.multiplier == 1) &&
+ (frequencyScaler.divisor == 1) &&
+ (mPeriod == mPeriodBase)) return;
- mPeriod = mPeriodBase * multiplier / divisor;
+ mPeriod = mPeriodBase * frequencyScaler.multiplier / frequencyScaler.divisor;
mThread->updateModel(mPeriod, mPhase, mReferenceTime);
}
diff --git a/services/surfaceflinger/Scheduler/DispSync.h b/services/surfaceflinger/Scheduler/DispSync.h
index 183966f..b3aef2d 100644
--- a/services/surfaceflinger/Scheduler/DispSync.h
+++ b/services/surfaceflinger/Scheduler/DispSync.h
@@ -24,6 +24,7 @@
#include <utils/Timers.h>
#include <ui/FenceTime.h>
+#include <DisplayHardware/HWC2.h>
#include <memory>
@@ -48,7 +49,7 @@
virtual bool addResyncSample(nsecs_t timestamp) = 0;
virtual void endResync() = 0;
virtual void setPeriod(nsecs_t period) = 0;
- virtual void scalePeriod(const uint32_t multiplier, uint32_t divisor) = 0;
+ virtual void scalePeriod(HWC2::Device::FrequencyScaler) = 0;
virtual nsecs_t getPeriod() = 0;
virtual void setRefreshSkipCount(int count) = 0;
virtual status_t addEventListener(const char* name, nsecs_t phase, Callback* callback) = 0;
@@ -122,7 +123,7 @@
// scale the vsync event model's period. The function is added
// for an experimental test mode and should not be used outside
// of that purpose.
- void scalePeriod(const uint32_t multiplier, uint32_t divisor);
+ void scalePeriod(HWC2::Device::FrequencyScaler frequencyScaler);
// The getPeriod method returns the current vsync period.
nsecs_t getPeriod() override;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index ae39202..5acfe59 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -47,7 +47,7 @@
#include <gui/IDisplayEventConnection.h>
#include <gui/LayerDebugInfo.h>
#include <gui/Surface.h>
-
+#include <renderengine/RenderEngine.h>
#include <ui/GraphicBufferAllocator.h>
#include <ui/PixelFormat.h>
#include <ui/UiConfig.h>
@@ -82,7 +82,6 @@
#include "DisplayHardware/HWComposer.h"
#include "DisplayHardware/VirtualDisplaySurface.h"
#include "Effects/Daltonizer.h"
-#include "RenderEngine/RenderEngine.h"
#include "Scheduler/DispSync.h"
#include "Scheduler/DispSyncSource.h"
#include "Scheduler/EventControlThread.h"
@@ -91,8 +90,11 @@
#include <cutils/compiler.h>
+#include "android-base/stringprintf.h"
+
#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
#include <android/hardware/configstore/1.1/ISurfaceFlingerConfigs.h>
+#include <android/hardware/configstore/1.2/ISurfaceFlingerConfigs.h>
#include <android/hardware/configstore/1.1/types.h>
#include <configstore/Utils.h>
@@ -141,6 +143,21 @@
return false;
}
+ui::Transform::orientation_flags fromSurfaceComposerRotation(ISurfaceComposer::Rotation rotation) {
+ switch (rotation) {
+ case ISurfaceComposer::eRotateNone:
+ return ui::Transform::ROT_0;
+ case ISurfaceComposer::eRotate90:
+ return ui::Transform::ROT_90;
+ case ISurfaceComposer::eRotate180:
+ return ui::Transform::ROT_180;
+ case ISurfaceComposer::eRotate270:
+ return ui::Transform::ROT_270;
+ }
+ ALOGE("Invalid rotation passed to captureScreen(): %d\n", rotation);
+ return ui::Transform::ROT_0;
+}
+
#pragma clang diagnostic pop
class ConditionalLock {
@@ -176,6 +193,7 @@
int64_t SurfaceFlinger::maxFrameBufferAcquiredBuffers;
// TODO(courtneygo): Rename hasWideColorDisplay to clarify its actual meaning.
bool SurfaceFlinger::hasWideColorDisplay;
+bool SurfaceFlinger::useColorManagement;
std::string getHwcServiceName() {
@@ -259,8 +277,6 @@
mDebugDDMS(0),
mDebugDisableHWC(0),
mDebugDisableTransformHint(0),
- mDebugInSwapBuffers(0),
- mLastSwapBufferTime(0),
mDebugInTransaction(0),
mLastTransactionTime(0),
mForceFullDamage(false),
@@ -304,6 +320,8 @@
hasWideColorDisplay =
getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasWideColorDisplay>(false);
+ useColorManagement =
+ getBool<V1_2::ISurfaceFlingerConfigs, &V1_2::ISurfaceFlingerConfigs::useColorManagement>(false);
V1_1::DisplayOrientation primaryDisplayOrientation =
getDisplayOrientation< V1_1::ISurfaceFlingerConfigs, &V1_1::ISurfaceFlingerConfigs::primaryDisplayOrientation>(
@@ -599,11 +617,10 @@
mVsyncModulator.setEventThreads(mSFEventThread.get(), mEventThread.get());
// Get a RenderEngine for the given display / config (can't fail)
+ int32_t renderEngineFeature = 0;
+ renderEngineFeature |= (useColorManagement ? RE::RenderEngine::USE_COLOR_MANAGEMENT : 0);
getBE().mRenderEngine =
- RE::impl::RenderEngine::create(HAL_PIXEL_FORMAT_RGBA_8888,
- hasWideColorDisplay
- ? RE::RenderEngine::WIDE_COLOR_SUPPORT
- : 0);
+ RE::impl::RenderEngine::create(HAL_PIXEL_FORMAT_RGBA_8888, renderEngineFeature);
LOG_ALWAYS_FATAL_IF(getBE().mRenderEngine == nullptr, "couldn't create RenderEngine");
LOG_ALWAYS_FATAL_IF(mVrFlingerRequestsDisplay,
@@ -777,18 +794,18 @@
// TODO: Not sure if display density should handled by SF any longer
class Density {
- static int getDensityFromProperty(char const* propName) {
+ static float getDensityFromProperty(char const* propName) {
char property[PROPERTY_VALUE_MAX];
- int density = 0;
+ float density = 0.0f;
if (property_get(propName, property, nullptr) > 0) {
- density = atoi(property);
+ density = strtof(property, nullptr);
}
return density;
}
public:
- static int getEmuDensity() {
+ static float getEmuDensity() {
return getDensityFromProperty("qemu.sf.lcd_density"); }
- static int getBuildDensity() {
+ static float getBuildDensity() {
return getDensityFromProperty("ro.sf.lcd_density"); }
};
@@ -876,6 +893,21 @@
return NO_ERROR;
}
+status_t SurfaceFlinger::getDisplayViewport(const sp<IBinder>& display, Rect* outViewport) {
+ if (outViewport == nullptr || display.get() == nullptr) {
+ return BAD_VALUE;
+ }
+
+ sp<const DisplayDevice> device(getDisplayDevice(display));
+ if (device == nullptr) {
+ return BAD_VALUE;
+ }
+
+ *outViewport = device->getViewport();
+
+ return NO_ERROR;
+}
+
int SurfaceFlinger::getActiveConfig(const sp<IBinder>& displayToken) {
const auto display = getDisplayDevice(displayToken);
if (!display) {
@@ -1435,25 +1467,26 @@
return false;
}
-bool SurfaceFlinger::handleMessageInvalidate() {
- ATRACE_CALL();
- return handlePageFlip();
-}
-
void SurfaceFlinger::handleMessageRefresh() {
ATRACE_CALL();
mRefreshPending = false;
+ const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
preComposition();
rebuildLayerStacks();
calculateWorkingSet();
- beginFrame();
- prepareFrame();
- doDebugFlashRegions();
+ for (const auto& [token, display] : mDisplays) {
+ beginFrame(display);
+ prepareFrame(display);
+ doDebugFlashRegions(display, repaintEverything);
+ doComposition(display, repaintEverything);
+ }
+
doTracing("handleRefresh");
logLayerStats();
- doComposition();
+
+ postFrame();
postComposition();
mHadClientComposition = false;
@@ -1461,11 +1494,26 @@
mHadClientComposition = mHadClientComposition ||
getBE().mHwc->hasClientComposition(display->getId());
}
+
mVsyncModulator.onRefreshed(mHadClientComposition);
+ getBE().mEndOfFrameCompositionInfo = std::move(getBE().mCompositionInfo);
+ for (const auto& [token, display] : mDisplays) {
+ const auto displayId = display->getId();
+ for (auto& compositionInfo : getBE().mEndOfFrameCompositionInfo[displayId]) {
+ compositionInfo.hwc.hwcLayer = nullptr;
+ }
+ }
+
mLayersWithQueuedFrames.clear();
}
+
+bool SurfaceFlinger::handleMessageInvalidate() {
+ ATRACE_CALL();
+ return handlePageFlip();
+}
+
void SurfaceFlinger::calculateWorkingSet() {
ATRACE_CALL();
ALOGV(__FUNCTION__);
@@ -1532,7 +1580,7 @@
layer->setPerFrameData(display);
}
- if (hasWideColorDisplay) {
+ if (useColorManagement) {
ColorMode colorMode;
Dataspace dataSpace;
RenderIntent renderIntent;
@@ -1542,46 +1590,56 @@
}
mDrawingState.colorMatrixChanged = false;
+
+ for (const auto& [token, display] : mDisplays) {
+ const auto displayId = display->getId();
+ getBE().mCompositionInfo[displayId].clear();
+ for (auto& layer : display->getVisibleLayersSortedByZ()) {
+ auto displayId = display->getId();
+ layer->getBE().compositionInfo.compositionType = layer->getCompositionType(displayId);
+ if (!layer->setHwcLayer(displayId)) {
+ ALOGV("Need to create HWCLayer for %s", layer->getName().string());
+ }
+ layer->getBE().compositionInfo.hwc.displayId = displayId;
+ getBE().mCompositionInfo[displayId].push_back(layer->getBE().compositionInfo);
+ layer->getBE().compositionInfo.hwc.hwcLayer = nullptr;
+ }
+ }
}
-void SurfaceFlinger::doDebugFlashRegions()
+void SurfaceFlinger::doDebugFlashRegions(const sp<DisplayDevice>& display, bool repaintEverything)
{
// is debugging enabled
if (CC_LIKELY(!mDebugRegion))
return;
- const bool repaintEverything = mRepaintEverything;
- for (const auto& [token, display] : mDisplays) {
- if (display->isPoweredOn()) {
- // transform the dirty region into this screen's coordinate space
- const Region dirtyRegion = display->getDirtyRegion(repaintEverything);
- if (!dirtyRegion.isEmpty()) {
- // redraw the whole screen
- doComposeSurfaces(display);
+ if (display->isPoweredOn()) {
+ // transform the dirty region into this screen's coordinate space
+ const Region dirtyRegion(display->getDirtyRegion(repaintEverything));
+ if (!dirtyRegion.isEmpty()) {
+ // redraw the whole screen
+ doComposeSurfaces(display);
- // and draw the dirty region
- const int32_t height = display->getHeight();
- auto& engine(getRenderEngine());
- engine.fillRegionWithColor(dirtyRegion, height, 1, 0, 1, 1);
+ // and draw the dirty region
+ const int32_t height = display->getHeight();
+ auto& engine(getRenderEngine());
+ engine.fillRegionWithColor(dirtyRegion, height, 1, 0, 1, 1);
- display->swapBuffers(getHwComposer());
- }
+ display->swapBuffers(getHwComposer());
}
}
- postFramebuffer();
+ postFramebuffer(display);
if (mDebugRegion > 1) {
usleep(mDebugRegion * 1000);
}
- for (const auto& [token, display] : mDisplays) {
- if (!display->isPoweredOn()) {
- continue;
- }
-
+ if (display->isPoweredOn()) {
status_t result = display->prepareFrame(*getBE().mHwc);
- ALOGE_IF(result != NO_ERROR, "prepareFrame for display %d failed: %d (%s)",
+ ALOGE_IF(result != NO_ERROR,
+ "prepareFrame for display %d failed:"
+ " %d (%s)",
display->getId(), result, strerror(-result));
}
}
@@ -1945,80 +2003,85 @@
display->getBestColorMode(bestDataSpace, intent, outDataSpace, outMode, outRenderIntent);
}
-void SurfaceFlinger::beginFrame()
+void SurfaceFlinger::beginFrame(const sp<DisplayDevice>& display)
{
- for (const auto& [token, display] : mDisplays) {
- bool dirty = !display->getDirtyRegion(mRepaintEverything).isEmpty();
- bool empty = display->getVisibleLayersSortedByZ().size() == 0;
- bool wasEmpty = !display->lastCompositionHadVisibleLayers;
+ bool dirty = !display->getDirtyRegion(false).isEmpty();
+ bool empty = display->getVisibleLayersSortedByZ().size() == 0;
+ bool wasEmpty = !display->lastCompositionHadVisibleLayers;
- // If nothing has changed (!dirty), don't recompose.
- // If something changed, but we don't currently have any visible layers,
- // and didn't when we last did a composition, then skip it this time.
- // The second rule does two things:
- // - When all layers are removed from a display, we'll emit one black
- // frame, then nothing more until we get new layers.
- // - When a display is created with a private layer stack, we won't
- // emit any black frames until a layer is added to the layer stack.
- bool mustRecompose = dirty && !(empty && wasEmpty);
+ // If nothing has changed (!dirty), don't recompose.
+ // If something changed, but we don't currently have any visible layers,
+ // and didn't when we last did a composition, then skip it this time.
+ // The second rule does two things:
+ // - When all layers are removed from a display, we'll emit one black
+ // frame, then nothing more until we get new layers.
+ // - When a display is created with a private layer stack, we won't
+ // emit any black frames until a layer is added to the layer stack.
+ bool mustRecompose = dirty && !(empty && wasEmpty);
- ALOGV_IF(display->isVirtual(), "Display %d: %s composition (%sdirty %sempty %swasEmpty)",
- display->getId(), mustRecompose ? "doing" : "skipping", dirty ? "+" : "-",
- empty ? "+" : "-", wasEmpty ? "+" : "-");
+ ALOGV_IF(display->getDisplayType() == DisplayDevice::DISPLAY_VIRTUAL,
+ "id[%d]: %s composition (%sdirty %sempty %swasEmpty)", display->getId(),
+ mustRecompose ? "doing" : "skipping",
+ dirty ? "+" : "-",
+ empty ? "+" : "-",
+ wasEmpty ? "+" : "-");
- display->beginFrame(mustRecompose);
+ display->beginFrame(mustRecompose);
- if (mustRecompose) {
- display->lastCompositionHadVisibleLayers = !empty;
- }
+ if (mustRecompose) {
+ display->lastCompositionHadVisibleLayers = !empty;
}
}
-void SurfaceFlinger::prepareFrame()
+void SurfaceFlinger::prepareFrame(const sp<DisplayDevice>& display)
{
- for (const auto& [token, display] : mDisplays) {
- if (!display->isPoweredOn()) {
- continue;
- }
-
- status_t result = display->prepareFrame(*getBE().mHwc);
- ALOGE_IF(result != NO_ERROR, "prepareFrame for display %d failed: %d (%s)",
- display->getId(), result, strerror(-result));
+ if (!display->isPoweredOn()) {
+ return;
}
+
+ status_t result = display->prepareFrame(*getBE().mHwc);
+ ALOGE_IF(result != NO_ERROR,
+ "prepareFrame for display %d failed:"
+ " %d (%s)",
+ display->getId(), result, strerror(-result));
}
-void SurfaceFlinger::doComposition() {
+void SurfaceFlinger::doComposition(const sp<DisplayDevice>& display, bool repaintEverything) {
ATRACE_CALL();
ALOGV("doComposition");
- const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
- for (const auto& [token, display] : mDisplays) {
- if (display->isPoweredOn()) {
- // transform the dirty region into this screen's coordinate space
- const Region dirtyRegion = display->getDirtyRegion(repaintEverything);
+ if (display->isPoweredOn()) {
+ // transform the dirty region into this screen's coordinate space
+ const Region dirtyRegion(display->getDirtyRegion(repaintEverything));
- // repaint the framebuffer (if needed)
- doDisplayComposition(display, dirtyRegion);
+ // repaint the framebuffer (if needed)
+ doDisplayComposition(display, dirtyRegion);
- display->dirtyRegion.clear();
- display->flip();
- }
+ display->dirtyRegion.clear();
+ display->flip();
}
- postFramebuffer();
+ postFramebuffer(display);
}
-void SurfaceFlinger::postFramebuffer()
+void SurfaceFlinger::postFrame()
+{
+ // |mStateLock| not needed as we are on the main thread
+ if (getBE().mHwc->isConnected(HWC_DISPLAY_PRIMARY)) {
+ uint32_t flipCount = getDefaultDisplayDeviceLocked()->getPageFlipCount();
+ if (flipCount % LOG_FRAME_STATS_PERIOD == 0) {
+ logFrameStats();
+ }
+ }
+}
+
+void SurfaceFlinger::postFramebuffer(const sp<DisplayDevice>& display)
{
ATRACE_CALL();
ALOGV("postFramebuffer");
- const nsecs_t now = systemTime();
- mDebugInSwapBuffers = now;
+ mPostFramebufferTime = systemTime();
- for (const auto& [token, display] : mDisplays) {
- if (!display->isPoweredOn()) {
- continue;
- }
+ if (display->isPoweredOn()) {
const auto displayId = display->getId();
if (displayId >= 0) {
getBE().mHwc->presentAndGetReleaseFences(displayId);
@@ -2063,18 +2126,6 @@
getBE().mHwc->clearReleaseFences(displayId);
}
}
-
- mLastSwapBufferTime = systemTime() - now;
- mDebugInSwapBuffers = 0;
-
- // |mStateLock| not needed as we are on the main thread
- const auto display = getDefaultDisplayDeviceLocked();
- if (display && getHwComposer().isConnected(display->getId())) {
- const uint32_t flipCount = display->getPageFlipCount();
- if (flipCount % LOG_FRAME_STATS_PERIOD == 0) {
- logFrameStats();
- }
- }
}
void SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
@@ -2189,7 +2240,7 @@
HdrCapabilities hdrCapabilities;
int32_t supportedPerFrameMetadata = 0;
- if (hasWideColorDisplay && displayId >= 0) {
+ if (useColorManagement && displayId >= 0) {
std::vector<ColorMode> modes = getHwComposer().getColorModes(displayId);
for (ColorMode colorMode : modes) {
if (isWideColorMode(colorMode)) {
@@ -2895,22 +2946,17 @@
}
}
- if (!display->isPrimary()) {
- // 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 = display->getBounds();
- const Rect& scissor = display->getScissor();
- if (scissor != bounds) {
- // 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 Rect& bounds = display->getBounds();
+ const Rect& scissor = display->getScissor();
+ if (scissor != bounds) {
+ // 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
- // enable scissor for this frame
- const uint32_t height = display->getHeight();
- getBE().mRenderEngine->setScissor(scissor.left, height - scissor.bottom,
- scissor.getWidth(), scissor.getHeight());
- }
+ // enable scissor for this frame
+ const uint32_t height = display->getHeight();
+ getBE().mRenderEngine->setScissor(scissor.left, height - scissor.bottom,
+ scissor.getWidth(), scissor.getHeight());
}
}
@@ -3896,6 +3942,13 @@
}
if ((index < numArgs) &&
+ (args[index] == String16("--frame-composition"))) {
+ index++;
+ dumpFrameCompositionInfo(result);
+ dumpAll = false;
+ }
+
+ if ((index < numArgs) &&
(args[index] == String16("--display-identification"))) {
index++;
dumpDisplayIdentificationData(result);
@@ -4127,7 +4180,8 @@
}
void SurfaceFlinger::dumpWideColorInfo(String8& result) const {
- result.appendFormat("hasWideColorDisplay: %d\n", hasWideColorDisplay);
+ result.appendFormat("Device has wide color display: %d\n", hasWideColorDisplay);
+ result.appendFormat("Device uses color management: %d\n", useColorManagement);
result.appendFormat("DisplayColorSetting: %s\n",
decodeDisplayColorSetting(mDisplayColorSetting).c_str());
@@ -4152,6 +4206,31 @@
result.append("\n");
}
+void SurfaceFlinger::dumpFrameCompositionInfo(String8& result) const {
+ std::string stringResult;
+
+ for (const auto& [token, display] : mDisplays) {
+ const auto displayId = display->getId();
+ if (displayId == DisplayDevice::DISPLAY_ID_INVALID) {
+ continue;
+ }
+
+ const auto& compositionInfoIt = getBE().mEndOfFrameCompositionInfo.find(displayId);
+ if (compositionInfoIt == getBE().mEndOfFrameCompositionInfo.end()) {
+ break;
+ }
+ const auto& compositionInfoList = compositionInfoIt->second;
+ stringResult += base::StringPrintf("Display: %d\n", displayId);
+ stringResult += base::StringPrintf("numComponents: %zu\n", compositionInfoList.size());
+ for (const auto& compositionInfo : compositionInfoList) {
+ compositionInfo.dump(stringResult, nullptr);
+ stringResult += base::StringPrintf("\n");
+ }
+ }
+
+ result.append(stringResult.c_str());
+}
+
LayersProto SurfaceFlinger::dumpProtoInfo(LayerVector::StateSet stateSet) const {
LayersProto layersProto;
const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
@@ -4200,9 +4279,7 @@
// figure out if we're stuck somewhere
const nsecs_t now = systemTime();
- const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
const nsecs_t inTransaction(mDebugInTransaction);
- nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
/*
@@ -4280,6 +4357,10 @@
result.append(LayerProtoParser::layersToString(std::move(layerTree)).c_str());
result.append("\n");
+ result.append("\nFrame-Composition information:\n");
+ dumpFrameCompositionInfo(result);
+ result.append("\n");
+
/*
* Dump Display state
*/
@@ -4310,11 +4391,8 @@
result.appendFormat(" orientation=%d, isPoweredOn=%d\n", display->getOrientation(),
display->isPoweredOn());
}
- result.appendFormat(" last eglSwapBuffers() time: %f us\n"
- " last transaction time : %f us\n"
- " transaction-flags : %08x\n"
+ result.appendFormat(" transaction-flags : %08x\n"
" gpu_to_cpu_unsupported : %d\n",
- mLastSwapBufferTime / 1000.0, mLastTransactionTime / 1000.0,
mTransactionFlags, !mGpuToCpuSupported);
if (display) {
@@ -4326,9 +4404,6 @@
activeConfig->getDpiY());
}
- result.appendFormat(" eglSwapBuffers time: %f us\n",
- inSwapBuffersDuration/1000.0);
-
result.appendFormat(" transaction time: %f us\n",
inTransactionDuration/1000.0);
@@ -4441,7 +4516,6 @@
switch (static_cast<ISurfaceComposerTag>(code)) {
// These methods should at minimum make sure that the client requested
// access to SF.
- case AUTHENTICATE_SURFACE:
case BOOT_FINISHED:
case CLEAR_ANIMATION_FRAME_STATS:
case CREATE_CONNECTION:
@@ -4478,11 +4552,13 @@
// The following calls are currently used by clients that do not
// request necessary permissions. However, they do not expose any secret
// information, so it is OK to pass them.
+ case AUTHENTICATE_SURFACE:
case GET_ACTIVE_CONFIG:
case GET_BUILT_IN_DISPLAY:
case GET_DISPLAY_COLOR_MODES:
case GET_DISPLAY_CONFIGS:
case GET_DISPLAY_STATS:
+ case GET_DISPLAY_VIEWPORT:
case GET_SUPPORTED_FRAME_TIMESTAMPS:
// Calling setTransactionState is safe, because you need to have been
// granted a reference to Client* and Handle* to do anything with it.
@@ -4709,7 +4785,9 @@
repaintEverything();
return NO_ERROR;
}
- case 1024: { // Is wide color gamut rendering/color management supported?
+ // TODO(b/111505327): Find out whether the usage of 1024 can switch to 1030,
+ // deprecate 1024 if they can.
+ case 1024: { // Does device have wide color gamut display?
reply->writeBool(hasWideColorDisplay);
return NO_ERROR;
}
@@ -4741,7 +4819,7 @@
DisplayColorSetting setting = static_cast<DisplayColorSetting>(data.readInt32());
switch (setting) {
case DisplayColorSetting::MANAGED:
- reply->writeBool(hasWideColorDisplay);
+ reply->writeBool(useColorManagement);
break;
case DisplayColorSetting::UNMANAGED:
reply->writeBool(true);
@@ -4766,27 +4844,45 @@
// Code 1029 is an experimental feature that allows applications to
// simulate a high frequency panel by setting a multiplier and divisor
// on the VSYNC-sf clock. If either the multiplier or divisor are
- // 0, then the code will set both to 1 to return the VSYNC-sf clock
- // to it's normal frequency.
- int multiplier = data.readInt32();
- int divisor = data.readInt32();
+ // 0, then the code simply return the current multiplier and divisor.
+ HWC2::Device::FrequencyScaler frequencyScaler;
+ frequencyScaler.multiplier = data.readInt32();
+ frequencyScaler.divisor = data.readInt32();
- if ((multiplier == 0) || (divisor == 0)) {
- multiplier = 1;
- divisor = 1;
+ if ((frequencyScaler.multiplier == 0) || (frequencyScaler.divisor == 0)) {
+ frequencyScaler = getBE().mHwc->getDisplayFrequencyScaleParameters();
+ reply->writeInt32(frequencyScaler.multiplier);
+ reply->writeInt32(frequencyScaler.divisor);
+ return NO_ERROR;
}
- if ((multiplier == 1) && (divisor == 1)) {
+ if ((frequencyScaler.multiplier == 1) && (frequencyScaler.divisor == 1)) {
enableHardwareVsync();
} else {
disableHardwareVsync(true);
}
- getBE().mHwc->getActiveConfig(DisplayDevice::DISPLAY_PRIMARY)
- ->scalePanelFrequency(multiplier, divisor);
- mPrimaryDispSync->scalePeriod(multiplier, divisor);
+ mPrimaryDispSync->scalePeriod(frequencyScaler);
+ getBE().mHwc->setDisplayFrequencyScaleParameters(frequencyScaler);
- ATRACE_INT("PeriodMultiplier", multiplier);
- ATRACE_INT("PeriodDivisor", divisor);
+ ATRACE_INT("PeriodMultiplier", frequencyScaler.multiplier);
+ ATRACE_INT("PeriodDivisor", frequencyScaler.divisor);
+
+ const hwc2_display_t hwcDisplayId = getBE().mHwc->getActiveConfig(
+ DisplayDevice::DISPLAY_PRIMARY)->getDisplayId();
+
+ onHotplugReceived(getBE().mComposerSequenceId,
+ hwcDisplayId, HWC2::Connection::Disconnected);
+ onHotplugReceived(getBE().mComposerSequenceId,
+ hwcDisplayId, HWC2::Connection::Connected);
+ frequencyScaler = getBE().mHwc->getDisplayFrequencyScaleParameters();
+ reply->writeInt32(frequencyScaler.multiplier);
+ reply->writeInt32(frequencyScaler.divisor);
+
+ return NO_ERROR;
+ }
+ // Is device color managed?
+ case 1030: {
+ reply->writeBool(useColorManagement);
return NO_ERROR;
}
}
@@ -4821,10 +4917,50 @@
if (!displayToken) return BAD_VALUE;
- const auto display = getDisplayDeviceLocked(displayToken);
- if (!display) return BAD_VALUE;
+ auto renderAreaRotation = fromSurfaceComposerRotation(rotation);
- DisplayRenderArea renderArea(display, sourceCrop, reqHeight, reqWidth, rotation);
+ sp<DisplayDevice> display;
+ {
+ Mutex::Autolock _l(mStateLock);
+
+ display = getDisplayDeviceLocked(displayToken);
+ if (!display) return BAD_VALUE;
+
+ const Rect& dispScissor = display->getScissor();
+ if (!dispScissor.isEmpty()) {
+ sourceCrop.set(dispScissor);
+ // adb shell screencap will default reqWidth and reqHeight to zeros.
+ if (reqWidth == 0 || reqHeight == 0) {
+ reqWidth = uint32_t(display->getViewport().width());
+ reqHeight = uint32_t(display->getViewport().height());
+ }
+ }
+
+ // get screen geometry
+ uint32_t width = display->getWidth();
+ uint32_t height = display->getHeight();
+
+ if (renderAreaRotation & ui::Transform::ROT_90) {
+ std::swap(width, height);
+ }
+
+ if (mPrimaryDisplayOrientation & DisplayState::eOrientationSwapMask) {
+ std::swap(width, height);
+ }
+
+ if ((reqWidth > width) || (reqHeight > height)) {
+ ALOGE("size mismatch (%d, %d) > (%d, %d)", reqWidth, reqHeight, width, height);
+ } else {
+ if (reqWidth == 0) {
+ reqWidth = width;
+ }
+ if (reqHeight == 0) {
+ reqHeight = height;
+ }
+ }
+ }
+
+ DisplayRenderArea renderArea(display, sourceCrop, reqWidth, reqHeight, renderAreaRotation);
auto traverseLayers = std::bind(std::mem_fn(&SurfaceFlinger::traverseLayersInDisplay), this,
display, minLayerZ, maxLayerZ, std::placeholders::_1);
@@ -4840,7 +4976,7 @@
public:
LayerRenderArea(SurfaceFlinger* flinger, const sp<Layer>& layer, const Rect crop,
int32_t reqWidth, int32_t reqHeight, bool childrenOnly)
- : RenderArea(reqHeight, reqWidth, CaptureFill::CLEAR),
+ : RenderArea(reqWidth, reqHeight, CaptureFill::CLEAR),
mLayer(layer),
mCrop(crop),
mFlinger(flinger),
@@ -4932,6 +5068,14 @@
int32_t reqWidth = crop.width() * frameScale;
int32_t reqHeight = crop.height() * frameScale;
+ // really small crop or frameScale
+ if (reqWidth <= 0) {
+ reqWidth = 1;
+ }
+ if (reqHeight <= 0) {
+ reqHeight = 1;
+ }
+
LayerRenderArea renderArea(this, parent, crop, reqWidth, reqHeight, childrenOnly);
auto traverseLayers = [parent, childrenOnly](const LayerVector::Visitor& visitor) {
@@ -4953,8 +5097,6 @@
bool useIdentityTransform) {
ATRACE_CALL();
- renderArea.updateDimensions(mPrimaryDisplayOrientation);
-
const uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
*outBuffer = new GraphicBuffer(renderArea.getReqWidth(), renderArea.getReqHeight(),
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index f5d8eb4..ed9e212 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -100,6 +100,7 @@
class Surface;
class SurfaceFlingerBE;
class VSyncSource;
+struct CompositionInfo;
namespace impl {
class EventThread;
@@ -224,6 +225,9 @@
// use to differentiate callbacks from different hardware composer
// instances. Each hardware composer instance gets a different sequence id.
int32_t mComposerSequenceId;
+
+ std::unordered_map<int32_t, std::vector<CompositionInfo>> mCompositionInfo;
+ std::unordered_map<int32_t, std::vector<CompositionInfo>> mEndOfFrameCompositionInfo;
};
@@ -280,13 +284,13 @@
// FramebufferSurface
static int64_t maxFrameBufferAcquiredBuffers;
- // Indicate if platform supports color management on its
- // wide-color display. This is typically found on devices
- // with wide gamut (e.g. Display-P3) display.
- // This also allows devices with wide-color displays that don't
- // want to support color management to disable color management.
+ // Indicate if a device has wide color gamut display. This is typically
+ // found on devices with wide color gamut (e.g. Display-P3) display.
static bool hasWideColorDisplay;
+ // Indicate if device wants color management on its display.
+ static bool useColorManagement;
+
static char const* getServiceName() ANDROID_API {
return "SurfaceFlinger";
}
@@ -431,6 +435,7 @@
virtual status_t captureLayers(const sp<IBinder>& parentHandle, sp<GraphicBuffer>* outBuffer,
const Rect& sourceCrop, float frameScale, bool childrenOnly);
virtual status_t getDisplayStats(const sp<IBinder>& displayToken, DisplayStatInfo* stats);
+ virtual status_t getDisplayViewport(const sp<IBinder>& display, Rect* outViewport);
virtual status_t getDisplayConfigs(const sp<IBinder>& displayToken,
Vector<DisplayInfo>* configs);
virtual int getActiveConfig(const sp<IBinder>& displayToken);
@@ -673,14 +678,14 @@
* prior to any CompositionInfo handling and is not dependent on data in
* CompositionInfo
*/
- void beginFrame();
+ void beginFrame(const sp<DisplayDevice>& display);
/* prepareFrame - This function will call into the DisplayDevice to prepare a
* frame after CompositionInfo has been programmed. This provides a mechanism
* to prepare the hardware composer
*/
- void prepareFrame();
- void doComposition();
- void doDebugFlashRegions();
+ void prepareFrame(const sp<DisplayDevice>& display);
+ void doComposition(const sp<DisplayDevice>& display, bool repainEverything);
+ void doDebugFlashRegions(const sp<DisplayDevice>& display, bool repaintEverything);
void doTracing(const char* where);
void logLayerStats();
void doDisplayComposition(const sp<const DisplayDevice>& display, const Region& dirtyRegion);
@@ -688,7 +693,8 @@
// This fails if using GL and the surface has been destroyed.
bool doComposeSurfaces(const sp<const DisplayDevice>& display);
- void postFramebuffer();
+ void postFramebuffer(const sp<DisplayDevice>& display);
+ void postFrame();
void drawWormhole(const sp<const DisplayDevice>& display, const Region& region) const;
/* ------------------------------------------------------------------------
@@ -749,6 +755,7 @@
void dumpBufferingStats(String8& result) const;
void dumpDisplayIdentificationData(String8& result) const;
void dumpWideColorInfo(String8& result) const;
+ void dumpFrameCompositionInfo(String8& result) const;
LayersProto dumpProtoInfo(LayerVector::StateSet stateSet) const;
LayersProto dumpVisibleLayersProtoInfo(const DisplayDevice& display) const;
@@ -844,9 +851,9 @@
int mDebugDisableHWC;
int mDebugDisableTransformHint;
volatile nsecs_t mDebugInSwapBuffers;
- nsecs_t mLastSwapBufferTime;
volatile nsecs_t mDebugInTransaction;
nsecs_t mLastTransactionTime;
+ nsecs_t mPostFramebufferTime;
bool mForceFullDamage;
bool mPropagateBackpressure = true;
std::unique_ptr<SurfaceInterceptor> mInterceptor =
diff --git a/services/surfaceflinger/TimeStats/timestatsproto/timestats.proto b/services/surfaceflinger/TimeStats/timestatsproto/timestats.proto
index ab7527e..b8f38c2 100644
--- a/services/surfaceflinger/TimeStats/timestatsproto/timestats.proto
+++ b/services/surfaceflinger/TimeStats/timestatsproto/timestats.proto
@@ -20,10 +20,11 @@
option optimize_for = LITE_RUNTIME;
-// //depot/google3/java/com/google/android/apps/graphics/proto/timestats.proto
-// is based on this proto. Please only make valid protobuf changes to these
-// messages, and keep the other file in sync per Android release. Please also
-// do not include "option optimize_for = LITE_RUNTIME;" on google3 side.
+// //depot/google3/java/com/google/android/apps/graphics/stats/proto/
+// timestats.proto is based on this proto. Please only make valid protobuf
+// changes to these messages, and keep the other file in sync per Android
+// release. Please also do not include "option optimize_for = LITE_RUNTIME;" at
+// google3 side.
// Next tag: 7
message SFTimeStatsGlobalProto {
diff --git a/services/surfaceflinger/layerproto/layers.proto b/services/surfaceflinger/layerproto/layers.proto
index e34772f..7f882da 100644
--- a/services/surfaceflinger/layerproto/layers.proto
+++ b/services/surfaceflinger/layerproto/layers.proto
@@ -80,12 +80,12 @@
optional int32 hwc_composition_type = 35;
// If it's a buffer layer, indicate if the content is protected
optional bool is_protected = 36;
- // If active_buffer is not null, record its transform
- optional TransformProto buffer_transform = 37;
// Current frame number being rendered.
- optional uint64 curr_frame = 38;
+ optional uint64 curr_frame = 37;
// A list of barriers that the layer is waiting to update state.
- repeated BarrierLayerProto barrier_layer = 39;
+ repeated BarrierLayerProto barrier_layer = 38;
+ // If active_buffer is not null, record its transform.
+ optional TransformProto buffer_transform = 39;
}
message PositionProto {
diff --git a/services/surfaceflinger/tests/Credentials_test.cpp b/services/surfaceflinger/tests/Credentials_test.cpp
index cd57411..8e23eb8e 100644
--- a/services/surfaceflinger/tests/Credentials_test.cpp
+++ b/services/surfaceflinger/tests/Credentials_test.cpp
@@ -287,7 +287,15 @@
}
/**
- * Test for methods accessible directly through SurfaceFlinger:
+ * The following tests are for methods accessible directly through SurfaceFlinger.
+ */
+
+/**
+ * An app can pass a buffer queue to the media server and ask the media server to decode a DRM video
+ * to that buffer queue. The media server is the buffer producer in this case. Because the app may create
+ * its own buffer queue and act as the buffer consumer, the media server wants to be careful to avoid
+ * sending decoded video frames to the app. This is where authenticateSurfaceTexture call comes in, to check
+ * the consumer of a buffer queue is SurfaceFlinger.
*/
TEST_F(CredentialsTest, AuthenticateSurfaceTextureTest) {
setupBackgroundSurface();
@@ -296,7 +304,8 @@
sp<ISurfaceComposer> sf(ComposerService::getComposerService());
std::function<bool()> condition = [=]() { return sf->authenticateSurfaceTexture(producer); };
- ASSERT_NO_FATAL_FAILURE(checkWithPrivileges(condition, true, false));
+ // Anyone should be able to check if the consumer of the buffer queue is SF.
+ ASSERT_NO_FATAL_FAILURE(checkWithPrivileges(condition, true, true));
}
TEST_F(CredentialsTest, GetLayerDebugInfo) {
diff --git a/services/surfaceflinger/tests/fakehwc/Android.bp b/services/surfaceflinger/tests/fakehwc/Android.bp
index 6ad1b87..a5b522e 100644
--- a/services/surfaceflinger/tests/fakehwc/Android.bp
+++ b/services/surfaceflinger/tests/fakehwc/Android.bp
@@ -30,8 +30,9 @@
"libutils",
],
static_libs: [
+ "libgmock",
+ "librenderengine",
"libtrace_proto",
- "libgmock"
],
header_libs: [
"android.hardware.graphics.composer@2.1-command-buffer",
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index b4aec36..1f57b8e 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -137,6 +137,7 @@
// Default to no wide color display support configured
mFlinger.mutableHasWideColorDisplay() = false;
+ mFlinger.mutableUseColorManagement() = false;
mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::UNMANAGED;
// Default to using HWC virtual displays
@@ -455,6 +456,7 @@
static void injectConfigChange(DisplayTransactionTest* test) {
test->mFlinger.mutableHasWideColorDisplay() = false;
+ test->mFlinger.mutableUseColorManagement() = false;
test->mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::UNMANAGED;
}
@@ -473,6 +475,7 @@
static constexpr bool WIDE_COLOR_SUPPORTED = true;
static void injectConfigChange(DisplayTransactionTest* test) {
+ test->mFlinger.mutableUseColorManagement() = true;
test->mFlinger.mutableHasWideColorDisplay() = true;
test->mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::UNMANAGED;
}
@@ -501,6 +504,7 @@
static constexpr bool WIDE_COLOR_SUPPORTED = false;
static void injectConfigChange(DisplayTransactionTest* test) {
+ test->mFlinger.mutableUseColorManagement() = true;
test->mFlinger.mutableHasWideColorDisplay() = true;
}
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 9df4264..d8e7581 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -113,6 +113,7 @@
*/
auto& mutableHasWideColorDisplay() { return SurfaceFlinger::hasWideColorDisplay; }
+ auto& mutableUseColorManagement() { return SurfaceFlinger::useColorManagement; }
auto& mutableDisplayTokens() { return mFlinger->mDisplayTokens; }
auto& mutableCurrentState() { return mFlinger->mCurrentState; }
diff --git a/services/surfaceflinger/tests/unittests/mock/MockDispSync.h b/services/surfaceflinger/tests/unittests/mock/MockDispSync.h
index 06a6b69..46d6558 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockDispSync.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockDispSync.h
@@ -35,7 +35,7 @@
MOCK_METHOD1(addResyncSample, bool(nsecs_t));
MOCK_METHOD0(endResync, void());
MOCK_METHOD1(setPeriod, void(nsecs_t));
- MOCK_METHOD2(scalePeriod, void(uint32_t, uint32_t));
+ MOCK_METHOD1(scalePeriod, void(HWC2::Device::FrequencyScaler));
MOCK_METHOD0(getPeriod, nsecs_t());
MOCK_METHOD1(setRefreshSkipCount, void(int));
MOCK_METHOD3(addEventListener, status_t(const char*, nsecs_t, Callback*));
diff --git a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h b/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h
index 36f74b6..b907c49 100644
--- a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h
+++ b/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h
@@ -18,11 +18,11 @@
#include <gmock/gmock.h>
-#include "RenderEngine/Image.h"
-#include "RenderEngine/Mesh.h"
-#include "RenderEngine/RenderEngine.h"
-#include "RenderEngine/Surface.h"
-#include "RenderEngine/Texture.h"
+#include <renderengine/Image.h>
+#include <renderengine/Mesh.h>
+#include <renderengine/RenderEngine.h>
+#include <renderengine/Surface.h>
+#include <renderengine/Texture.h>
namespace android {
namespace RE {
diff --git a/services/vr/hardware_composer/impl/vr_hwc.cpp b/services/vr/hardware_composer/impl/vr_hwc.cpp
index d1ed12b..417460c 100644
--- a/services/vr/hardware_composer/impl/vr_hwc.cpp
+++ b/services/vr/hardware_composer/impl/vr_hwc.cpp
@@ -332,10 +332,14 @@
return Error::NONE;
}
-Error VrHwc::getClientTargetSupport(Display /* display */, uint32_t /* width */,
+Error VrHwc::getClientTargetSupport(Display display, uint32_t /* width */,
uint32_t /* height */,
PixelFormat /* format */,
Dataspace /* dataspace */) {
+ std::lock_guard<std::mutex> guard(mutex_);
+ if (!FindDisplay(display))
+ return Error::BAD_DISPLAY;
+
return Error::NONE;
}
@@ -466,16 +470,37 @@
if (!display_ptr)
return Error::BAD_DISPLAY;
+ if (mode < ColorMode::NATIVE || mode > ColorMode::DISPLAY_P3)
+ return Error::BAD_PARAMETER;
+
display_ptr->set_color_mode(mode);
return Error::NONE;
}
Error VrHwc::setPowerMode(Display display, IComposerClient::PowerMode mode) {
+ bool dozeSupported = false;
+
+ Error dozeSupportError = getDozeSupport(display, &dozeSupported);
+
+ if (dozeSupportError != Error::NONE)
+ return dozeSupportError;
+
std::lock_guard<std::mutex> guard(mutex_);
auto display_ptr = FindDisplay(display);
if (!display_ptr)
return Error::BAD_DISPLAY;
+ if (mode < IComposerClient::PowerMode::OFF ||
+ mode > IComposerClient::PowerMode::DOZE_SUSPEND) {
+ return Error::BAD_PARAMETER;
+ }
+
+ if (!dozeSupported &&
+ (mode == IComposerClient::PowerMode::DOZE ||
+ mode == IComposerClient::PowerMode::DOZE_SUSPEND)) {
+ return Error::UNSUPPORTED;
+ }
+
display_ptr->set_power_mode(mode);
return Error::NONE;
}