Merge "Add getDisplayViewport for screenrecord tool"
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index e1094d8..f48aa47 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -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/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/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp
index 7eeaabb..f8bb94e 100644
--- a/services/surfaceflinger/ColorLayer.cpp
+++ b/services/surfaceflinger/ColorLayer.cpp
@@ -89,6 +89,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 +98,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 +108,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 +118,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/Layer.cpp b/services/surfaceflinger/Layer.cpp
index f7f3fac..8e6cf99 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -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;
}
}
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 6ebd668..56ed765 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -513,6 +513,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.h b/services/surfaceflinger/LayerBE.h
index 3055621..0413a45 100644
--- a/services/surfaceflinger/LayerBE.h
+++ b/services/surfaceflinger/LayerBE.h
@@ -55,6 +55,8 @@
ui::Dataspace dataspace;
hwc_color_t color;
bool clearClientTarget = false;
+ bool supportedPerFrameMetadata = false;
+ HdrMetadata hdrMetadata;
} hwc;
struct {
Mesh* mesh;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 31152c4..eeb74ec 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -259,8 +259,6 @@
mDebugDDMS(0),
mDebugDisableHWC(0),
mDebugDisableTransformHint(0),
- mDebugInSwapBuffers(0),
- mLastSwapBufferTime(0),
mDebugInTransaction(0),
mLastTransactionTime(0),
mForceFullDamage(false),
@@ -1450,25 +1448,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;
@@ -1476,9 +1475,19 @@
mHadClientComposition = mHadClientComposition ||
getBE().mHwc->hasClientComposition(display->getId());
}
+
mVsyncModulator.onRefreshed(mHadClientComposition);
mLayersWithQueuedFrames.clear();
+ for (auto& compositionInfo : getBE().mCompositionInfo) {
+ compositionInfo.hwc.hwcLayer = nullptr;
+ }
+}
+
+
+bool SurfaceFlinger::handleMessageInvalidate() {
+ ATRACE_CALL();
+ return handlePageFlip();
}
void SurfaceFlinger::calculateWorkingSet() {
@@ -1557,46 +1566,54 @@
}
mDrawingState.colorMatrixChanged = false;
+ getBE().mCompositionInfo.clear();
+
+ for (const auto& [token, display] : mDisplays) {
+ 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());
+ }
+ getBE().mCompositionInfo.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));
}
}
@@ -1960,80 +1977,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(displayDevice->getDisplayType() == DisplayDevice::DISPLAY_VIRTUAL,
+ "dpy[%zu]: %s composition (%sdirty %sempty %swasEmpty)", dpy,
+ 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);
@@ -2078,18 +2100,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)
@@ -4215,9 +4225,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;
/*
@@ -4325,11 +4333,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) {
@@ -4341,9 +4346,6 @@
activeConfig->getDpiY());
}
- result.appendFormat(" eglSwapBuffers time: %f us\n",
- inSwapBuffersDuration/1000.0);
-
result.appendFormat(" transaction time: %f us\n",
inTransactionDuration/1000.0);
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 273ce22..c95356e 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,8 @@
// use to differentiate callbacks from different hardware composer
// instances. Each hardware composer instance gets a different sequence id.
int32_t mComposerSequenceId;
+
+ std::vector<CompositionInfo> mCompositionInfo;
};
@@ -674,14 +677,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);
@@ -689,7 +692,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;
/* ------------------------------------------------------------------------
@@ -845,9 +849,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 =