From 0c69cad13dda09f1df1dbf23810b1c5b7f28ba08 Mon Sep 17 00:00:00 2001 From: David Sodman Date: Mon, 21 Aug 2017 12:12:51 -0700 Subject: Refactor Layer/ColorLayer into siblings New class hierarchy should look like: Layer (abstract) / \ / \ Buffer Color Layer Layer Note: LayerBuffer is what previously was referred to by class Layer Test: Transaction_test.cpp/manual test Change-Id: I372a27d533e08371da37be811e4372404f7787bd --- services/surfaceflinger/BufferLayer.cpp | 911 ++++++++++++++++++++++++++++++++ 1 file changed, 911 insertions(+) create mode 100644 services/surfaceflinger/BufferLayer.cpp (limited to 'services/surfaceflinger/BufferLayer.cpp') diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp new file mode 100644 index 0000000000..ccb65f6df2 --- /dev/null +++ b/services/surfaceflinger/BufferLayer.cpp @@ -0,0 +1,911 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//#define LOG_NDEBUG 0 +#undef LOG_TAG +#define LOG_TAG "BufferLayer" +#define ATRACE_TAG ATRACE_TAG_GRAPHICS + +#include "BufferLayer.h" +#include "Colorizer.h" +#include "DisplayDevice.h" +#include "LayerRejecter.h" +#include "clz.h" + +#include "RenderEngine/RenderEngine.h" + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +namespace android { + +BufferLayer::BufferLayer(SurfaceFlinger* flinger, const sp& client, const String8& name, + uint32_t w, uint32_t h, uint32_t flags) + : Layer(flinger, client, name, w, h, flags), + mTextureName(-1U), + mFormat(PIXEL_FORMAT_NONE), + mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), + mBufferLatched(false), + mPreviousFrameNumber(0), + mUpdateTexImageFailed(false), + mRefreshPending(false) { +#ifdef USE_HWC2 + ALOGV("Creating Layer %s", name.string()); +#endif + + mFlinger->getRenderEngine().genTextures(1, &mTextureName); + mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName); + + if (flags & ISurfaceComposerClient::eNonPremultiplied) mPremultipliedAlpha = false; + + mCurrentState.requested = mCurrentState.active; + + // drawing state & current state are identical + mDrawingState = mCurrentState; +} + +BufferLayer::~BufferLayer() { + sp c(mClientRef.promote()); + if (c != 0) { + c->detachLayer(this); + } + + for (auto& point : mRemoteSyncPoints) { + point->setTransactionApplied(); + } + for (auto& point : mLocalSyncPoints) { + point->setFrameAvailable(); + } + mFlinger->deleteTextureAsync(mTextureName); + +#ifdef USE_HWC2 + if (!mHwcLayers.empty()) { + ALOGE("Found stale hardware composer layers when destroying " + "surface flinger layer %s", + mName.string()); + destroyAllHwcLayers(); + } +#endif +} + +bool BufferLayer::isProtected() const +{ + const sp& activeBuffer(mActiveBuffer); + return (activeBuffer != 0) && + (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED); +} + +bool BufferLayer::isVisible() const { + return !(isHiddenByPolicy()) && getAlpha() > 0.0f && + (mActiveBuffer != NULL || mSidebandStream != NULL); +} + +bool BufferLayer::isFixedSize() const { + return getEffectiveScalingMode() != NATIVE_WINDOW_SCALING_MODE_FREEZE; +} + +status_t BufferLayer::setBuffers(uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) { + uint32_t const maxSurfaceDims = + min(mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims()); + + // never allow a surface larger than what our underlying GL implementation + // can handle. + if ((uint32_t(w) > maxSurfaceDims) || (uint32_t(h) > maxSurfaceDims)) { + ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h)); + return BAD_VALUE; + } + + mFormat = format; + + mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false; + mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false; + mCurrentOpacity = getOpacityForFormat(format); + + mSurfaceFlingerConsumer->setDefaultBufferSize(w, h); + mSurfaceFlingerConsumer->setDefaultBufferFormat(format); + mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0)); + + return NO_ERROR; +} + +static constexpr mat4 inverseOrientation(uint32_t transform) { + const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1); + const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1); + const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1); + mat4 tr; + + if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90) { + tr = tr * rot90; + } + if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H) { + tr = tr * flipH; + } + if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V) { + tr = tr * flipV; + } + return inverse(tr); +} + +/* + * onDraw will draw the current layer onto the presentable buffer + */ +void BufferLayer::onDraw(const RenderArea& renderArea, const Region& clip, + bool useIdentityTransform) const { + ATRACE_CALL(); + + if (CC_UNLIKELY(mActiveBuffer == 0)) { + // the texture has not been created yet, this Layer has + // in fact never been drawn into. This happens frequently with + // SurfaceView because the WindowManager can't know when the client + // has drawn the first time. + + // If there is nothing under us, we paint the screen in black, otherwise + // we just skip this update. + + // figure out if there is something below us + Region under; + bool finished = false; + mFlinger->mDrawingState.traverseInZOrder([&](Layer* layer) { + if (finished || layer == static_cast(this)) { + finished = true; + return; + } + under.orSelf(renderArea.getTransform().transform(layer->visibleRegion)); + }); + // if not everything below us is covered, we plug the holes! + Region holes(clip.subtract(under)); + if (!holes.isEmpty()) { + clearWithOpenGL(renderArea, 0, 0, 0, 1); + } + return; + } + + // Bind the current buffer to the GL texture, and wait for it to be + // ready for us to draw into. + status_t err = mSurfaceFlingerConsumer->bindTextureImage(); + if (err != NO_ERROR) { + ALOGW("onDraw: bindTextureImage failed (err=%d)", err); + // Go ahead and draw the buffer anyway; no matter what we do the screen + // is probably going to have something visibly wrong. + } + + bool blackOutLayer = isProtected() || (isSecure() && !renderArea.isSecure()); + + RenderEngine& engine(mFlinger->getRenderEngine()); + + if (!blackOutLayer) { + // TODO: we could be more subtle with isFixedSize() + const bool useFiltering = getFiltering() || needsFiltering(renderArea) || isFixedSize(); + + // Query the texture matrix given our current filtering mode. + float textureMatrix[16]; + mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering); + mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix); + + if (getTransformToDisplayInverse()) { + /* + * the code below applies the primary display's inverse transform to + * the texture transform + */ + uint32_t transform = DisplayDevice::getPrimaryDisplayOrientationTransform(); + mat4 tr = inverseOrientation(transform); + + /** + * TODO(b/36727915): This is basically a hack. + * + * Ensure that regardless of the parent transformation, + * this buffer is always transformed from native display + * orientation to display orientation. For example, in the case + * of a camera where the buffer remains in native orientation, + * we want the pixels to always be upright. + */ + sp p = mDrawingParent.promote(); + if (p != nullptr) { + const auto parentTransform = p->getTransform(); + tr = tr * inverseOrientation(parentTransform.getOrientation()); + } + + // and finally apply it to the original texture matrix + const mat4 texTransform(mat4(static_cast(textureMatrix)) * tr); + memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix)); + } + + // Set things up for texturing. + mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight()); + mTexture.setFiltering(useFiltering); + mTexture.setMatrix(textureMatrix); + + engine.setupLayerTexturing(mTexture); + } else { + engine.setupLayerBlackedOut(); + } + drawWithOpenGL(renderArea, useIdentityTransform); + engine.disableTexturing(); +} + +bool BufferLayer::onPreComposition(nsecs_t refreshStartTime) { + if (mBufferLatched) { + Mutex::Autolock lock(mFrameEventHistoryMutex); + mFrameEventHistory.addPreComposition(mCurrentFrameNumber, refreshStartTime); + } + mRefreshPending = false; + return mQueuedFrames > 0 || mSidebandStreamChanged || mAutoRefresh; +} + +#ifdef USE_HWC2 +void BufferLayer::releasePendingBuffer(nsecs_t dequeueReadyTime) { + if (!mSurfaceFlingerConsumer->releasePendingBuffer()) { + return; + } + + auto releaseFenceTime = + std::make_shared(mSurfaceFlingerConsumer->getPrevFinalReleaseFence()); + mReleaseTimeline.updateSignalTimes(); + mReleaseTimeline.push(releaseFenceTime); + + Mutex::Autolock lock(mFrameEventHistoryMutex); + if (mPreviousFrameNumber != 0) { + mFrameEventHistory.addRelease(mPreviousFrameNumber, dequeueReadyTime, + std::move(releaseFenceTime)); + } +} +#endif + +Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime) { + ATRACE_CALL(); + + if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) { + // mSidebandStreamChanged was true + mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream(); + if (mSidebandStream != NULL) { + setTransactionFlags(eTransactionNeeded); + mFlinger->setTransactionFlags(eTraversalNeeded); + } + recomputeVisibleRegions = true; + + const State& s(getDrawingState()); + return getTransform().transform(Region(Rect(s.active.w, s.active.h))); + } + + Region outDirtyRegion; + if (mQueuedFrames <= 0 && !mAutoRefresh) { + return outDirtyRegion; + } + + // if we've already called updateTexImage() without going through + // a composition step, we have to skip this layer at this point + // because we cannot call updateTeximage() without a corresponding + // compositionComplete() call. + // we'll trigger an update in onPreComposition(). + if (mRefreshPending) { + return outDirtyRegion; + } + + // If the head buffer's acquire fence hasn't signaled yet, return and + // try again later + if (!headFenceHasSignaled()) { + mFlinger->signalLayerUpdate(); + return outDirtyRegion; + } + + // Capture the old state of the layer for comparisons later + const State& s(getDrawingState()); + const bool oldOpacity = isOpaque(s); + sp oldActiveBuffer = mActiveBuffer; + + if (!allTransactionsSignaled()) { + mFlinger->signalLayerUpdate(); + return outDirtyRegion; + } + + // This boolean is used to make sure that SurfaceFlinger's shadow copy + // of the buffer queue isn't modified when the buffer queue is returning + // BufferItem's that weren't actually queued. This can happen in shared + // buffer mode. + bool queuedBuffer = false; + LayerRejecter r(mDrawingState, getCurrentState(), recomputeVisibleRegions, + getProducerStickyTransform() != 0, mName.string(), mOverrideScalingMode, + mFreezeGeometryUpdates); + status_t updateResult = + mSurfaceFlingerConsumer->updateTexImage(&r, mFlinger->mPrimaryDispSync, &mAutoRefresh, + &queuedBuffer, mLastFrameNumberReceived); + if (updateResult == BufferQueue::PRESENT_LATER) { + // Producer doesn't want buffer to be displayed yet. Signal a + // layer update so we check again at the next opportunity. + mFlinger->signalLayerUpdate(); + return outDirtyRegion; + } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) { + // If the buffer has been rejected, remove it from the shadow queue + // and return early + if (queuedBuffer) { + Mutex::Autolock lock(mQueueItemLock); + mQueueItems.removeAt(0); + android_atomic_dec(&mQueuedFrames); + } + return outDirtyRegion; + } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) { + // This can occur if something goes wrong when trying to create the + // EGLImage for this buffer. If this happens, the buffer has already + // been released, so we need to clean up the queue and bug out + // early. + if (queuedBuffer) { + Mutex::Autolock lock(mQueueItemLock); + mQueueItems.clear(); + android_atomic_and(0, &mQueuedFrames); + } + + // Once we have hit this state, the shadow queue may no longer + // correctly reflect the incoming BufferQueue's contents, so even if + // updateTexImage starts working, the only safe course of action is + // to continue to ignore updates. + mUpdateTexImageFailed = true; + + return outDirtyRegion; + } + + if (queuedBuffer) { + // Autolock scope + auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber(); + + Mutex::Autolock lock(mQueueItemLock); + + // Remove any stale buffers that have been dropped during + // updateTexImage + while (mQueueItems[0].mFrameNumber != currentFrameNumber) { + mQueueItems.removeAt(0); + android_atomic_dec(&mQueuedFrames); + } + + mQueueItems.removeAt(0); + } + + // Decrement the queued-frames count. Signal another event if we + // have more frames pending. + if ((queuedBuffer && android_atomic_dec(&mQueuedFrames) > 1) || mAutoRefresh) { + mFlinger->signalLayerUpdate(); + } + + // update the active buffer + mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer(&mActiveBufferSlot); + if (mActiveBuffer == NULL) { + // this can only happen if the very first buffer was rejected. + return outDirtyRegion; + } + + mBufferLatched = true; + mPreviousFrameNumber = mCurrentFrameNumber; + mCurrentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber(); + + { + Mutex::Autolock lock(mFrameEventHistoryMutex); + mFrameEventHistory.addLatch(mCurrentFrameNumber, latchTime); +#ifndef USE_HWC2 + auto releaseFenceTime = + std::make_shared(mSurfaceFlingerConsumer->getPrevFinalReleaseFence()); + mReleaseTimeline.updateSignalTimes(); + mReleaseTimeline.push(releaseFenceTime); + if (mPreviousFrameNumber != 0) { + mFrameEventHistory.addRelease(mPreviousFrameNumber, latchTime, + std::move(releaseFenceTime)); + } +#endif + } + + mRefreshPending = true; + mFrameLatencyNeeded = true; + if (oldActiveBuffer == NULL) { + // the first time we receive a buffer, we need to trigger a + // geometry invalidation. + recomputeVisibleRegions = true; + } + + setDataSpace(mSurfaceFlingerConsumer->getCurrentDataSpace()); + + Rect crop(mSurfaceFlingerConsumer->getCurrentCrop()); + const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform()); + const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode()); + if ((crop != mCurrentCrop) || (transform != mCurrentTransform) || + (scalingMode != mCurrentScalingMode)) { + mCurrentCrop = crop; + mCurrentTransform = transform; + mCurrentScalingMode = scalingMode; + recomputeVisibleRegions = true; + } + + if (oldActiveBuffer != NULL) { + uint32_t bufWidth = mActiveBuffer->getWidth(); + uint32_t bufHeight = mActiveBuffer->getHeight(); + if (bufWidth != uint32_t(oldActiveBuffer->width) || + bufHeight != uint32_t(oldActiveBuffer->height)) { + recomputeVisibleRegions = true; + } + } + + mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format); + if (oldOpacity != isOpaque(s)) { + recomputeVisibleRegions = true; + } + + // Remove any sync points corresponding to the buffer which was just + // latched + { + Mutex::Autolock lock(mLocalSyncPointMutex); + auto point = mLocalSyncPoints.begin(); + while (point != mLocalSyncPoints.end()) { + if (!(*point)->frameIsAvailable() || !(*point)->transactionIsApplied()) { + // This sync point must have been added since we started + // latching. Don't drop it yet. + ++point; + continue; + } + + if ((*point)->getFrameNumber() <= mCurrentFrameNumber) { + point = mLocalSyncPoints.erase(point); + } else { + ++point; + } + } + } + + // FIXME: postedRegion should be dirty & bounds + Region dirtyRegion(Rect(s.active.w, s.active.h)); + + // transform the dirty region to window-manager space + outDirtyRegion = (getTransform().transform(dirtyRegion)); + + return outDirtyRegion; +} + +#ifdef USE_HWC2 +void BufferLayer::setPerFrameData(const sp& displayDevice) { + // Apply this display's projection's viewport to the visible region + // before giving it to the HWC HAL. + const Transform& tr = displayDevice->getTransform(); + const auto& viewport = displayDevice->getViewport(); + Region visible = tr.transform(visibleRegion.intersect(viewport)); + auto hwcId = displayDevice->getHwcDisplayId(); + auto& hwcInfo = mHwcLayers[hwcId]; + auto& hwcLayer = hwcInfo.layer; + auto error = hwcLayer->setVisibleRegion(visible); + if (error != HWC2::Error::None) { + ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(), + to_string(error).c_str(), static_cast(error)); + visible.dump(LOG_TAG); + } + + error = hwcLayer->setSurfaceDamage(surfaceDamageRegion); + if (error != HWC2::Error::None) { + ALOGE("[%s] Failed to set surface damage: %s (%d)", mName.string(), + to_string(error).c_str(), static_cast(error)); + surfaceDamageRegion.dump(LOG_TAG); + } + + // Sideband layers + if (mSidebandStream.get()) { + setCompositionType(hwcId, HWC2::Composition::Sideband); + ALOGV("[%s] Requesting Sideband composition", mName.string()); + error = hwcLayer->setSidebandStream(mSidebandStream->handle()); + if (error != HWC2::Error::None) { + ALOGE("[%s] Failed to set sideband stream %p: %s (%d)", mName.string(), + mSidebandStream->handle(), to_string(error).c_str(), static_cast(error)); + } + return; + } + + // Client layers + if (hwcInfo.forceClientComposition || + (mActiveBuffer != nullptr && mActiveBuffer->handle == nullptr)) { + ALOGV("[%s] Requesting Client composition", mName.string()); + setCompositionType(hwcId, HWC2::Composition::Client); + return; + } + + // SolidColor layers + if (mActiveBuffer == nullptr) { + setCompositionType(hwcId, HWC2::Composition::SolidColor); + + // For now, we only support black for DimLayer + error = hwcLayer->setColor({0, 0, 0, 255}); + if (error != HWC2::Error::None) { + ALOGE("[%s] Failed to set color: %s (%d)", mName.string(), to_string(error).c_str(), + static_cast(error)); + } + + // Clear out the transform, because it doesn't make sense absent a + // source buffer + error = hwcLayer->setTransform(HWC2::Transform::None); + if (error != HWC2::Error::None) { + ALOGE("[%s] Failed to clear transform: %s (%d)", mName.string(), + to_string(error).c_str(), static_cast(error)); + } + + return; + } + + // Device or Cursor layers + if (mPotentialCursor) { + ALOGV("[%s] Requesting Cursor composition", mName.string()); + setCompositionType(hwcId, HWC2::Composition::Cursor); + } else { + ALOGV("[%s] Requesting Device composition", mName.string()); + setCompositionType(hwcId, HWC2::Composition::Device); + } + + ALOGV("setPerFrameData: dataspace = %d", mCurrentState.dataSpace); + error = hwcLayer->setDataspace(mCurrentState.dataSpace); + if (error != HWC2::Error::None) { + ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), mCurrentState.dataSpace, + to_string(error).c_str(), static_cast(error)); + } + + uint32_t hwcSlot = 0; + sp hwcBuffer; + hwcInfo.bufferCache.getHwcBuffer(mActiveBufferSlot, mActiveBuffer, &hwcSlot, &hwcBuffer); + + auto acquireFence = mSurfaceFlingerConsumer->getCurrentFence(); + error = hwcLayer->setBuffer(hwcSlot, hwcBuffer, acquireFence); + if (error != HWC2::Error::None) { + ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(), mActiveBuffer->handle, + to_string(error).c_str(), static_cast(error)); + } +} + +#else +void BufferLayer::setPerFrameData(const sp& hw, + HWComposer::HWCLayerInterface& layer) { + // we have to set the visible region on every frame because + // we currently free it during onLayerDisplayed(), which is called + // after HWComposer::commit() -- every frame. + // Apply this display's projection's viewport to the visible region + // before giving it to the HWC HAL. + const Transform& tr = hw->getTransform(); + Region visible = tr.transform(visibleRegion.intersect(hw->getViewport())); + layer.setVisibleRegionScreen(visible); + layer.setSurfaceDamage(surfaceDamageRegion); + mIsGlesComposition = (layer.getCompositionType() == HWC_FRAMEBUFFER); + + if (mSidebandStream.get()) { + layer.setSidebandStream(mSidebandStream); + } else { + // NOTE: buffer can be NULL if the client never drew into this + // layer yet, or if we ran out of memory + layer.setBuffer(mActiveBuffer); + } +} +#endif + +bool BufferLayer::isOpaque(const Layer::State& s) const +{ + // if we don't have a buffer or sidebandStream yet, we're translucent regardless of the + // layer's opaque flag. + if ((mSidebandStream == nullptr) && (mActiveBuffer == nullptr)) { + return false; + } + + // if the layer has the opaque flag, then we're always opaque, + // otherwise we use the current buffer's format. + return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity; +} + +void BufferLayer::onFirstRef() { + // Creates a custom BufferQueue for SurfaceFlingerConsumer to use + sp producer; + sp consumer; + BufferQueue::createBufferQueue(&producer, &consumer, true); + mProducer = new MonitoredProducer(producer, mFlinger, this); + mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName, this); + mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0)); + mSurfaceFlingerConsumer->setContentsChangedListener(this); + mSurfaceFlingerConsumer->setName(mName); + + if (mFlinger->isLayerTripleBufferingDisabled()) { + mProducer->setMaxDequeuedBufferCount(2); + } + + const sp hw(mFlinger->getDefaultDisplayDevice()); + updateTransformHint(hw); +} + +// --------------------------------------------------------------------------- +// Interface implementation for SurfaceFlingerConsumer::ContentsChangedListener +// --------------------------------------------------------------------------- + +void BufferLayer::onFrameAvailable(const BufferItem& item) { + // Add this buffer from our internal queue tracker + { // Autolock scope + Mutex::Autolock lock(mQueueItemLock); + mFlinger->mInterceptor.saveBufferUpdate(this, item.mGraphicBuffer->getWidth(), + item.mGraphicBuffer->getHeight(), + item.mFrameNumber); + // Reset the frame number tracker when we receive the first buffer after + // a frame number reset + if (item.mFrameNumber == 1) { + mLastFrameNumberReceived = 0; + } + + // Ensure that callbacks are handled in order + while (item.mFrameNumber != mLastFrameNumberReceived + 1) { + status_t result = mQueueItemCondition.waitRelative(mQueueItemLock, ms2ns(500)); + if (result != NO_ERROR) { + ALOGE("[%s] Timed out waiting on callback", mName.string()); + } + } + + mQueueItems.push_back(item); + android_atomic_inc(&mQueuedFrames); + + // Wake up any pending callbacks + mLastFrameNumberReceived = item.mFrameNumber; + mQueueItemCondition.broadcast(); + } + + mFlinger->signalLayerUpdate(); +} + +void BufferLayer::onFrameReplaced(const BufferItem& item) { + { // Autolock scope + Mutex::Autolock lock(mQueueItemLock); + + // Ensure that callbacks are handled in order + while (item.mFrameNumber != mLastFrameNumberReceived + 1) { + status_t result = mQueueItemCondition.waitRelative(mQueueItemLock, ms2ns(500)); + if (result != NO_ERROR) { + ALOGE("[%s] Timed out waiting on callback", mName.string()); + } + } + + if (mQueueItems.empty()) { + ALOGE("Can't replace a frame on an empty queue"); + return; + } + mQueueItems.editItemAt(mQueueItems.size() - 1) = item; + + // Wake up any pending callbacks + mLastFrameNumberReceived = item.mFrameNumber; + mQueueItemCondition.broadcast(); + } +} + +void BufferLayer::onSidebandStreamChanged() { + if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) { + // mSidebandStreamChanged was false + mFlinger->signalLayerUpdate(); + } +} + +bool BufferLayer::needsFiltering(const RenderArea& renderArea) const { + return mNeedsFiltering || renderArea.needsFiltering(); +} + +// As documented in libhardware header, formats in the range +// 0x100 - 0x1FF are specific to the HAL implementation, and +// are known to have no alpha channel +// TODO: move definition for device-specific range into +// hardware.h, instead of using hard-coded values here. +#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF) + +bool BufferLayer::getOpacityForFormat(uint32_t format) { + if (HARDWARE_IS_DEVICE_FORMAT(format)) { + return true; + } + switch (format) { + case HAL_PIXEL_FORMAT_RGBA_8888: + case HAL_PIXEL_FORMAT_BGRA_8888: + case HAL_PIXEL_FORMAT_RGBA_FP16: + case HAL_PIXEL_FORMAT_RGBA_1010102: + return false; + } + // in all other case, we have no blending (also for unknown formats) + return true; +} + +void BufferLayer::drawWithOpenGL(const RenderArea& renderArea, + bool useIdentityTransform) const { + const State& s(getDrawingState()); + + computeGeometry(renderArea, mMesh, useIdentityTransform); + + /* + * NOTE: the way we compute the texture coordinates here produces + * different results than when we take the HWC path -- in the later case + * the "source crop" is rounded to texel boundaries. + * This can produce significantly different results when the texture + * is scaled by a large amount. + * + * The GL code below is more logical (imho), and the difference with + * HWC is due to a limitation of the HWC API to integers -- a question + * is suspend is whether we should ignore this problem or revert to + * GL composition when a buffer scaling is applied (maybe with some + * minimal value)? Or, we could make GL behave like HWC -- but this feel + * like more of a hack. + */ + Rect win(computeBounds()); + + Transform t = getTransform(); + if (!s.finalCrop.isEmpty()) { + win = t.transform(win); + if (!win.intersect(s.finalCrop, &win)) { + win.clear(); + } + win = t.inverse().transform(win); + if (!win.intersect(computeBounds(), &win)) { + win.clear(); + } + } + + float left = float(win.left) / float(s.active.w); + float top = float(win.top) / float(s.active.h); + float right = float(win.right) / float(s.active.w); + float bottom = float(win.bottom) / float(s.active.h); + + // TODO: we probably want to generate the texture coords with the mesh + // here we assume that we only have 4 vertices + Mesh::VertexArray texCoords(mMesh.getTexCoordArray()); + texCoords[0] = vec2(left, 1.0f - top); + texCoords[1] = vec2(left, 1.0f - bottom); + texCoords[2] = vec2(right, 1.0f - bottom); + texCoords[3] = vec2(right, 1.0f - top); + + RenderEngine& engine(mFlinger->getRenderEngine()); + engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), false /* disableTexture */, + getColor()); +#ifdef USE_HWC2 + engine.setSourceDataSpace(mCurrentState.dataSpace); +#endif + engine.drawMesh(mMesh); + engine.disableBlending(); +} + +uint32_t BufferLayer::getProducerStickyTransform() const { + int producerStickyTransform = 0; + int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform); + if (ret != OK) { + ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__, + strerror(-ret), ret); + return 0; + } + return static_cast(producerStickyTransform); +} + +bool BufferLayer::latchUnsignaledBuffers() { + static bool propertyLoaded = false; + static bool latch = false; + static std::mutex mutex; + std::lock_guard lock(mutex); + if (!propertyLoaded) { + char value[PROPERTY_VALUE_MAX] = {}; + property_get("debug.sf.latch_unsignaled", value, "0"); + latch = atoi(value); + propertyLoaded = true; + } + return latch; +} + +uint64_t BufferLayer::getHeadFrameNumber() const { + Mutex::Autolock lock(mQueueItemLock); + if (!mQueueItems.empty()) { + return mQueueItems[0].mFrameNumber; + } else { + return mCurrentFrameNumber; + } +} + +bool BufferLayer::headFenceHasSignaled() const { +#ifdef USE_HWC2 + if (latchUnsignaledBuffers()) { + return true; + } + + Mutex::Autolock lock(mQueueItemLock); + if (mQueueItems.empty()) { + return true; + } + if (mQueueItems[0].mIsDroppable) { + // Even though this buffer's fence may not have signaled yet, it could + // be replaced by another buffer before it has a chance to, which means + // that it's possible to get into a situation where a buffer is never + // able to be latched. To avoid this, grab this buffer anyway. + return true; + } + return mQueueItems[0].mFenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING; +#else + return true; +#endif +} + +uint32_t BufferLayer::getEffectiveScalingMode() const { + if (mOverrideScalingMode >= 0) { + return mOverrideScalingMode; + } + return mCurrentScalingMode; +} + +// ---------------------------------------------------------------------------- +// transaction +// ---------------------------------------------------------------------------- + +void BufferLayer::notifyAvailableFrames() { + auto headFrameNumber = getHeadFrameNumber(); + bool headFenceSignaled = headFenceHasSignaled(); + Mutex::Autolock lock(mLocalSyncPointMutex); + for (auto& point : mLocalSyncPoints) { + if (headFrameNumber >= point->getFrameNumber() && headFenceSignaled) { + point->setFrameAvailable(); + } + } +} + +sp BufferLayer::getProducer() const { + return mProducer; +} + +// --------------------------------------------------------------------------- +// h/w composer set-up +// --------------------------------------------------------------------------- + +bool BufferLayer::allTransactionsSignaled() { + auto headFrameNumber = getHeadFrameNumber(); + bool matchingFramesFound = false; + bool allTransactionsApplied = true; + Mutex::Autolock lock(mLocalSyncPointMutex); + + for (auto& point : mLocalSyncPoints) { + if (point->getFrameNumber() > headFrameNumber) { + break; + } + matchingFramesFound = true; + + if (!point->frameIsAvailable()) { + // We haven't notified the remote layer that the frame for + // this point is available yet. Notify it now, and then + // abort this attempt to latch. + point->setFrameAvailable(); + allTransactionsApplied = false; + break; + } + + allTransactionsApplied = allTransactionsApplied && point->transactionIsApplied(); + } + return !matchingFramesFound || allTransactionsApplied; +} + +} // namespace android + +#if defined(__gl_h_) +#error "don't include gl/gl.h in this file" +#endif + +#if defined(__gl2_h_) +#error "don't include gl2/gl2.h in this file" +#endif -- cgit v1.2.3-59-g8ed1b From 41fdfc920e2a479add53a1936c3ae76cdbea41db Mon Sep 17 00:00:00 2001 From: David Sodman Date: Mon, 6 Nov 2017 16:09:56 -0800 Subject: Run clang-format on Layer/SurfaceFlinger files Run clang-format on changes introduced by the Layer refactor Test: Compile/Manual run Change-Id: I3042cb265d2a00c694f0d6d29cce878dbb069f50 --- services/surfaceflinger/BufferLayer.cpp | 18 +- services/surfaceflinger/BufferLayer.h | 8 +- services/surfaceflinger/ColorLayer.cpp | 14 +- services/surfaceflinger/ColorLayer.h | 8 +- services/surfaceflinger/Layer.cpp | 434 +++++++++++++------------------- services/surfaceflinger/Layer.h | 125 ++++----- 6 files changed, 252 insertions(+), 355 deletions(-) mode change 100755 => 100644 services/surfaceflinger/Layer.cpp (limited to 'services/surfaceflinger/BufferLayer.cpp') diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index ccb65f6df2..8f5dea2691 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -99,11 +99,9 @@ BufferLayer::~BufferLayer() { #endif } -bool BufferLayer::isProtected() const -{ +bool BufferLayer::isProtected() const { const sp& activeBuffer(mActiveBuffer); - return (activeBuffer != 0) && - (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED); + return (activeBuffer != 0) && (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED); } bool BufferLayer::isVisible() const { @@ -140,9 +138,9 @@ status_t BufferLayer::setBuffers(uint32_t w, uint32_t h, PixelFormat format, uin } static constexpr mat4 inverseOrientation(uint32_t transform) { - const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1); - const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1); - const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1); + const mat4 flipH(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1); + const mat4 flipV(1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1); + const mat4 rot90(0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1); mat4 tr; if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90) { @@ -605,8 +603,7 @@ void BufferLayer::setPerFrameData(const sp& hw, } #endif -bool BufferLayer::isOpaque(const Layer::State& s) const -{ +bool BufferLayer::isOpaque(const Layer::State& s) const { // if we don't have a buffer or sidebandStream yet, we're translucent regardless of the // layer's opaque flag. if ((mSidebandStream == nullptr) && (mActiveBuffer == nullptr)) { @@ -730,8 +727,7 @@ bool BufferLayer::getOpacityForFormat(uint32_t format) { return true; } -void BufferLayer::drawWithOpenGL(const RenderArea& renderArea, - bool useIdentityTransform) const { +void BufferLayer::drawWithOpenGL(const RenderArea& renderArea, bool useIdentityTransform) const { const State& s(getDrawingState()); computeGeometry(renderArea, mMesh, useIdentityTransform); diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h index b245f2976e..882649ba70 100644 --- a/services/surfaceflinger/BufferLayer.h +++ b/services/surfaceflinger/BufferLayer.h @@ -16,8 +16,8 @@ #pragma once -#include "Layer.h" #include "Client.h" +#include "Layer.h" #include "DisplayHardware/HWComposer.h" #include "DisplayHardware/HWComposerBufferCache.h" #include "FrameTracker.h" @@ -118,7 +118,8 @@ public: #ifdef USE_HWC2 void setPerFrameData(const sp& displayDevice); #else - void setPerFrameData(const sp& hw, HWComposer::HWCLayerInterface& layer); + void setPerFrameData(const sp& hw, + HWComposer::HWCLayerInterface& layer); #endif bool isOpaque(const Layer::State& s) const override; @@ -137,8 +138,7 @@ private: static bool getOpacityForFormat(uint32_t format); // drawing - void drawWithOpenGL(const RenderArea& renderArea, - bool useIdentityTransform) const; + void drawWithOpenGL(const RenderArea& renderArea, bool useIdentityTransform) const; // Temporary - Used only for LEGACY camera mode. uint32_t getProducerStickyTransform() const; diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp index 72fdaaa654..500f81f263 100644 --- a/services/surfaceflinger/ColorLayer.cpp +++ b/services/surfaceflinger/ColorLayer.cpp @@ -18,8 +18,8 @@ #undef LOG_TAG #define LOG_TAG "ColorLayer" -#include #include +#include #include #include @@ -28,17 +28,16 @@ #include #include "ColorLayer.h" -#include "SurfaceFlinger.h" #include "DisplayDevice.h" #include "RenderEngine/RenderEngine.h" +#include "SurfaceFlinger.h" namespace android { // --------------------------------------------------------------------------- -ColorLayer::ColorLayer(SurfaceFlinger* flinger, const sp& client, - const String8& name, uint32_t w, uint32_t h, uint32_t flags) +ColorLayer::ColorLayer(SurfaceFlinger* flinger, const sp& client, const String8& name, + uint32_t w, uint32_t h, uint32_t flags) : Layer(flinger, client, name, w, h, flags) { - // drawing state & current state are identical mDrawingState = mCurrentState; } @@ -46,12 +45,12 @@ ColorLayer::ColorLayer(SurfaceFlinger* flinger, const sp& client, void ColorLayer::onDraw(const RenderArea& renderArea, const Region& /* clip */, bool useIdentityTransform) const { const State& s(getDrawingState()); - if (s.color.a>0) { + if (s.color.a > 0) { Mesh mesh(Mesh::TRIANGLE_FAN, 4, 2); computeGeometry(renderArea, mesh, useIdentityTransform); RenderEngine& engine(mFlinger->getRenderEngine()); engine.setupLayerBlending(getPremultipledAlpha(), false /* opaque */, - true /* disableTexture */, s.color); + true /* disableTexture */, s.color); engine.drawMesh(mesh); engine.disableBlending(); } @@ -62,7 +61,6 @@ bool ColorLayer::isVisible() const { return !isHiddenByPolicy() && s.color.a; } - // --------------------------------------------------------------------------- }; // namespace android diff --git a/services/surfaceflinger/ColorLayer.h b/services/surfaceflinger/ColorLayer.h index c68ad023e1..89013274af 100644 --- a/services/surfaceflinger/ColorLayer.h +++ b/services/surfaceflinger/ColorLayer.h @@ -28,16 +28,16 @@ namespace android { class ColorLayer : public Layer { public: - ColorLayer(SurfaceFlinger* flinger, const sp& client, - const String8& name, uint32_t w, uint32_t h, uint32_t flags); + ColorLayer(SurfaceFlinger* flinger, const sp& client, const String8& name, uint32_t w, + uint32_t h, uint32_t flags); virtual ~ColorLayer() = default; virtual const char* getTypeId() const { return "ColorLayer"; } virtual void onDraw(const RenderArea& renderArea, const Region& clip, - bool useIdentityTransform) const; + bool useIdentityTransform) const; bool isVisible() const override; virtual bool isOpaque(const Layer::State&) const { return false; } - virtual bool isFixedSize() const { return true; } + virtual bool isFixedSize() const { return true; } void notifyAvailableFrames() override {} PixelFormat getPixelFormat() const override { return PIXEL_FORMAT_NONE; } diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp old mode 100755 new mode 100644 index 763488c8f5..a318a8f46a --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -19,10 +19,10 @@ #define LOG_TAG "Layer" #define ATRACE_TAG ATRACE_TAG_GRAPHICS -#include +#include #include +#include #include -#include #include #include @@ -43,13 +43,13 @@ #include #include -#include "clz.h" #include "Colorizer.h" #include "DisplayDevice.h" #include "Layer.h" #include "LayerRejecter.h" #include "MonitoredProducer.h" #include "SurfaceFlinger.h" +#include "clz.h" #include "DisplayHardware/HWComposer.h" @@ -58,14 +58,14 @@ #include #include "LayerProtoHelper.h" -#define DEBUG_RESIZE 0 +#define DEBUG_RESIZE 0 namespace android { int32_t Layer::sSequence = 1; -Layer::Layer(SurfaceFlinger* flinger, const sp& client, - const String8& name, uint32_t w, uint32_t h, uint32_t flags) +Layer::Layer(SurfaceFlinger* flinger, const sp& client, const String8& name, uint32_t w, + uint32_t h, uint32_t flags) : contentDirty(false), sequence(uint32_t(android_atomic_inc(&sSequence))), mFlinger(flinger), @@ -97,18 +97,14 @@ Layer::Layer(SurfaceFlinger* flinger, const sp& client, mQueueItems(), mLastFrameNumberReceived(0), mAutoRefresh(false), - mFreezeGeometryUpdates(false) -{ + mFreezeGeometryUpdates(false) { mCurrentCrop.makeInvalid(); uint32_t layerFlags = 0; - if (flags & ISurfaceComposerClient::eHidden) - layerFlags |= layer_state_t::eLayerHidden; - if (flags & ISurfaceComposerClient::eOpaque) - layerFlags |= layer_state_t::eLayerOpaque; - if (flags & ISurfaceComposerClient::eSecure) - layerFlags |= layer_state_t::eLayerSecure; + if (flags & ISurfaceComposerClient::eHidden) layerFlags |= layer_state_t::eLayerHidden; + if (flags & ISurfaceComposerClient::eOpaque) layerFlags |= layer_state_t::eLayerOpaque; + if (flags & ISurfaceComposerClient::eSecure) layerFlags |= layer_state_t::eLayerSecure; mName = name; mTransactionName = String8("TX - ") + mName; @@ -138,8 +134,7 @@ Layer::Layer(SurfaceFlinger* flinger, const sp& client, const auto& activeConfig = hwc.getActiveConfig(HWC_DISPLAY_PRIMARY); nsecs_t displayPeriod = activeConfig->getVsyncPeriod(); #else - nsecs_t displayPeriod = - flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY); + nsecs_t displayPeriod = flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY); #endif mFrameTracker.setDisplayRefreshPeriod(displayPeriod); @@ -148,8 +143,7 @@ Layer::Layer(SurfaceFlinger* flinger, const sp& client, mFrameEventHistory.initializeCompositorTiming(compositorTiming); } -void Layer::onFirstRef() { -} +void Layer::onFirstRef() {} Layer::~Layer() { mFrameTracker.logAndResetStats(mName); @@ -170,7 +164,7 @@ void Layer::onLayerDisplayed(const sp& releaseFence) { } #else void Layer::onLayerDisplayed(const sp& /* hw */, - HWComposer::HWCLayerInterface* layer) { + HWComposer::HWCLayerInterface* layer) { if (layer) { layer->onDisplayed(); mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence()); @@ -233,8 +227,7 @@ sp Layer::getHandle() { #ifdef USE_HWC2 bool Layer::createHwcLayer(HWComposer* hwc, int32_t hwcId) { - LOG_ALWAYS_FATAL_IF(mHwcLayers.count(hwcId) != 0, - "Already have a layer for hwcId %d", hwcId); + LOG_ALWAYS_FATAL_IF(mHwcLayers.count(hwcId) != 0, "Already have a layer for hwcId %d", hwcId); HWC2::Layer* layer = hwc->createLayer(hwcId); if (!layer) { return false; @@ -243,7 +236,7 @@ bool Layer::createHwcLayer(HWComposer* hwc, int32_t hwcId) { hwcInfo.hwc = hwc; hwcInfo.layer = layer; layer->setLayerDestroyedListener( - [this, hwcId] (HWC2::Layer* /*layer*/){mHwcLayers.erase(hwcId);}); + [this, hwcId](HWC2::Layer* /*layer*/) { mHwcLayers.erase(hwcId); }); return true; } @@ -252,14 +245,12 @@ void Layer::destroyHwcLayer(int32_t hwcId) { return; } auto& hwcInfo = mHwcLayers[hwcId]; - LOG_ALWAYS_FATAL_IF(hwcInfo.layer == nullptr, - "Attempt to destroy null layer"); + LOG_ALWAYS_FATAL_IF(hwcInfo.layer == nullptr, "Attempt to destroy null layer"); LOG_ALWAYS_FATAL_IF(hwcInfo.hwc == nullptr, "Missing HWComposer"); hwcInfo.hwc->destroyLayer(hwcId, hwcInfo.layer); // The layer destroyed listener should have cleared the entry from // mHwcLayers. Verify that. - LOG_ALWAYS_FATAL_IF(mHwcLayers.count(hwcId) != 0, - "Stale layer entry in mHwcLayers"); + LOG_ALWAYS_FATAL_IF(mHwcLayers.count(hwcId) != 0, "Stale layer entry in mHwcLayers"); } void Layer::destroyAllHwcLayers() { @@ -269,7 +260,7 @@ void Layer::destroyAllHwcLayers() { destroyHwcLayer(mHwcLayers.begin()->first); } LOG_ALWAYS_FATAL_IF(!mHwcLayers.empty(), - "All hardware composer layers should have been destroyed"); + "All hardware composer layers should have been destroyed"); } #endif @@ -393,7 +384,7 @@ Rect Layer::computeInitialCrop(const sp& hw) const { activeCrop.clear(); } if (!s.finalCrop.isEmpty()) { - if(!activeCrop.intersect(s.finalCrop, &activeCrop)) { + if (!activeCrop.intersect(s.finalCrop, &activeCrop)) { activeCrop.clear(); } } @@ -443,16 +434,13 @@ FloatRect Layer::computeCrop(const sp& hw) const { * the code below applies the primary display's inverse transform to the * buffer */ - uint32_t invTransformOrient = - DisplayDevice::getPrimaryDisplayOrientationTransform(); + uint32_t invTransformOrient = DisplayDevice::getPrimaryDisplayOrientationTransform(); // calculate the inverse transform if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) { - invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | - NATIVE_WINDOW_TRANSFORM_FLIP_H; + invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | NATIVE_WINDOW_TRANSFORM_FLIP_H; } // and apply to the current transform - invTransform = (Transform(invTransformOrient) * Transform(invTransform)) - .getOrientation(); + invTransform = (Transform(invTransformOrient) * Transform(invTransform)).getOrientation(); } int winWidth = s.active.w; @@ -466,27 +454,25 @@ FloatRect Layer::computeCrop(const sp& hw) const { bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0; bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0; if (is_h_flipped == is_v_flipped) { - invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | - NATIVE_WINDOW_TRANSFORM_FLIP_H; + invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | NATIVE_WINDOW_TRANSFORM_FLIP_H; } winWidth = s.active.h; winHeight = s.active.w; } - const Rect winCrop = activeCrop.transform( - invTransform, s.active.w, s.active.h); + const Rect winCrop = activeCrop.transform(invTransform, s.active.w, s.active.h); // below, crop is intersected with winCrop expressed in crop's coordinate space - float xScale = crop.getWidth() / float(winWidth); + float xScale = crop.getWidth() / float(winWidth); float yScale = crop.getHeight() / float(winHeight); - float insetL = winCrop.left * xScale; - float insetT = winCrop.top * yScale; - float insetR = (winWidth - winCrop.right ) * xScale; + float insetL = winCrop.left * xScale; + float insetT = winCrop.top * yScale; + float insetR = (winWidth - winCrop.right) * xScale; float insetB = (winHeight - winCrop.bottom) * yScale; - crop.left += insetL; - crop.top += insetT; - crop.right -= insetR; + crop.left += insetL; + crop.top += insetT; + crop.right -= insetR; crop.bottom -= insetB; return crop; @@ -495,9 +481,7 @@ FloatRect Layer::computeCrop(const sp& hw) const { #ifdef USE_HWC2 void Layer::setGeometry(const sp& displayDevice, uint32_t z) #else -void Layer::setGeometry( - const sp& hw, - HWComposer::HWCLayerInterface& layer) +void Layer::setGeometry(const sp& hw, HWComposer::HWCLayerInterface& layer) #endif { #ifdef USE_HWC2 @@ -529,18 +513,18 @@ void Layer::setGeometry( #ifdef USE_HWC2 auto blendMode = HWC2::BlendMode::None; if (!isOpaque(s) || getAlpha() != 1.0f) { - blendMode = mPremultipliedAlpha ? - HWC2::BlendMode::Premultiplied : HWC2::BlendMode::Coverage; + blendMode = + mPremultipliedAlpha ? HWC2::BlendMode::Premultiplied : HWC2::BlendMode::Coverage; } auto error = hwcLayer->setBlendMode(blendMode); - ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set blend mode %s:" - " %s (%d)", mName.string(), to_string(blendMode).c_str(), - to_string(error).c_str(), static_cast(error)); + ALOGE_IF(error != HWC2::Error::None, + "[%s] Failed to set blend mode %s:" + " %s (%d)", + mName.string(), to_string(blendMode).c_str(), to_string(error).c_str(), + static_cast(error)); #else if (!isOpaque(s) || getAlpha() != 1.0f) { - layer.setBlending(mPremultipliedAlpha ? - HWC_BLENDING_PREMULT : - HWC_BLENDING_COVERAGE); + layer.setBlending(mPremultipliedAlpha ? HWC_BLENDING_PREMULT : HWC_BLENDING_COVERAGE); } #endif @@ -552,9 +536,9 @@ void Layer::setGeometry( Rect activeCrop(s.crop); activeCrop = t.transform(activeCrop); #ifdef USE_HWC2 - if(!activeCrop.intersect(displayDevice->getViewport(), &activeCrop)) { + if (!activeCrop.intersect(displayDevice->getViewport(), &activeCrop)) { #else - if(!activeCrop.intersect(hw->getViewport(), &activeCrop)) { + if (!activeCrop.intersect(hw->getViewport(), &activeCrop)) { #endif activeCrop.clear(); } @@ -565,22 +549,20 @@ void Layer::setGeometry( // transform.inverse().transform(transform.transform(Rect)) != Rect // in which case we need to make sure the final rect is clipped to the // display bounds. - if(!activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop)) { + if (!activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop)) { activeCrop.clear(); } // mark regions outside the crop as transparent activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top)); - activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom, - s.active.w, s.active.h)); - activeTransparentRegion.orSelf(Rect(0, activeCrop.top, - activeCrop.left, activeCrop.bottom)); - activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top, - s.active.w, activeCrop.bottom)); + activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom, s.active.w, s.active.h)); + activeTransparentRegion.orSelf(Rect(0, activeCrop.top, activeCrop.left, activeCrop.bottom)); + activeTransparentRegion.orSelf( + Rect(activeCrop.right, activeCrop.top, s.active.w, activeCrop.bottom)); } Rect frame(t.transform(computeBounds(activeTransparentRegion))); if (!s.finalCrop.isEmpty()) { - if(!frame.intersect(s.finalCrop, &frame)) { + if (!frame.intersect(s.finalCrop, &frame)) { frame.clear(); } } @@ -592,10 +574,9 @@ void Layer::setGeometry( Rect transformedFrame = tr.transform(frame); error = hwcLayer->setDisplayFrame(transformedFrame); if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to set display frame [%d, %d, %d, %d]: %s (%d)", - mName.string(), transformedFrame.left, transformedFrame.top, - transformedFrame.right, transformedFrame.bottom, - to_string(error).c_str(), static_cast(error)); + ALOGE("[%s] Failed to set display frame [%d, %d, %d, %d]: %s (%d)", mName.string(), + transformedFrame.left, transformedFrame.top, transformedFrame.right, + transformedFrame.bottom, to_string(error).c_str(), static_cast(error)); } else { hwcInfo.displayFrame = transformedFrame; } @@ -604,23 +585,23 @@ void Layer::setGeometry( error = hwcLayer->setSourceCrop(sourceCrop); if (error != HWC2::Error::None) { ALOGE("[%s] Failed to set source crop [%.3f, %.3f, %.3f, %.3f]: " - "%s (%d)", mName.string(), sourceCrop.left, sourceCrop.top, - sourceCrop.right, sourceCrop.bottom, to_string(error).c_str(), - static_cast(error)); + "%s (%d)", + mName.string(), sourceCrop.left, sourceCrop.top, sourceCrop.right, sourceCrop.bottom, + to_string(error).c_str(), static_cast(error)); } else { hwcInfo.sourceCrop = sourceCrop; } float alpha = static_cast(getAlpha()); error = hwcLayer->setPlaneAlpha(alpha); - ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set plane alpha %.3f: " - "%s (%d)", mName.string(), alpha, to_string(error).c_str(), - static_cast(error)); + ALOGE_IF(error != HWC2::Error::None, + "[%s] Failed to set plane alpha %.3f: " + "%s (%d)", + mName.string(), alpha, to_string(error).c_str(), static_cast(error)); 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(error)); + ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set Z %u: %s (%d)", mName.string(), z, + to_string(error).c_str(), static_cast(error)); int type = s.type; int appId = s.appId; @@ -632,8 +613,8 @@ void Layer::setGeometry( } error = hwcLayer->setInfo(type, appId); - ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set info (%d)", - mName.string(), static_cast(error)); + ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set info (%d)", mName.string(), + static_cast(error)); #else if (!frame.intersect(hw->getViewport(), &frame)) { frame.clear(); @@ -641,7 +622,7 @@ void Layer::setGeometry( const Transform& tr(hw->getTransform()); layer.setFrame(tr.transform(frame)); layer.setCrop(computeCrop(hw)); - layer.setPlaneAlpha(static_cast(std::round(255.0f*getAlpha()))); + layer.setPlaneAlpha(static_cast(std::round(255.0f * getAlpha()))); #endif /* @@ -660,12 +641,10 @@ void Layer::setGeometry( * the code below applies the primary display's inverse transform to the * buffer */ - uint32_t invTransform = - DisplayDevice::getPrimaryDisplayOrientationTransform(); + uint32_t invTransform = DisplayDevice::getPrimaryDisplayOrientationTransform(); // calculate the inverse transform if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { - invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | - NATIVE_WINDOW_TRANSFORM_FLIP_H; + invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | NATIVE_WINDOW_TRANSFORM_FLIP_H; } /* @@ -686,9 +665,11 @@ void Layer::setGeometry( } else { auto transform = static_cast(orientation); auto error = hwcLayer->setTransform(transform); - ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set transform %s: " - "%s (%d)", mName.string(), to_string(transform).c_str(), - to_string(error).c_str(), static_cast(error)); + ALOGE_IF(error != HWC2::Error::None, + "[%s] Failed to set transform %s: " + "%s (%d)", + mName.string(), to_string(transform).c_str(), to_string(error).c_str(), + static_cast(error)); } #else if (orientation & Transform::ROT_INVALID) { @@ -722,14 +703,14 @@ void Layer::setPerFrameData(const sp& displayDevice) { auto error = hwcLayer->setVisibleRegion(visible); if (error != HWC2::Error::None) { ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(), - to_string(error).c_str(), static_cast(error)); + to_string(error).c_str(), static_cast(error)); visible.dump(LOG_TAG); } error = hwcLayer->setSurfaceDamage(surfaceDamageRegion); if (error != HWC2::Error::None) { ALOGE("[%s] Failed to set surface damage: %s (%d)", mName.string(), - to_string(error).c_str(), static_cast(error)); + to_string(error).c_str(), static_cast(error)); surfaceDamageRegion.dump(LOG_TAG); } @@ -739,16 +720,15 @@ void Layer::setPerFrameData(const sp& displayDevice) { ALOGV("[%s] Requesting Sideband composition", mName.string()); error = hwcLayer->setSidebandStream(mSidebandStream->handle()); if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to set sideband stream %p: %s (%d)", - mName.string(), mSidebandStream->handle(), - to_string(error).c_str(), static_cast(error)); + ALOGE("[%s] Failed to set sideband stream %p: %s (%d)", mName.string(), + mSidebandStream->handle(), to_string(error).c_str(), static_cast(error)); } return; } // Client layers if (hwcInfo.forceClientComposition || - (mActiveBuffer != nullptr && mActiveBuffer->handle == nullptr)) { + (mActiveBuffer != nullptr && mActiveBuffer->handle == nullptr)) { ALOGV("[%s] Requesting Client composition", mName.string()); setCompositionType(hwcId, HWC2::Composition::Client); return; @@ -759,13 +739,12 @@ void Layer::setPerFrameData(const sp& displayDevice) { setCompositionType(hwcId, HWC2::Composition::SolidColor); half4 color = getColor(); - error = hwcLayer->setColor({static_cast(std::round(255.0f*color.r)), - static_cast(std::round(255.0f * color.g)), - static_cast(std::round(255.0f * color.b)), - 255}); + error = hwcLayer->setColor({static_cast(std::round(255.0f * color.r)), + static_cast(std::round(255.0f * color.g)), + static_cast(std::round(255.0f * color.b)), 255}); if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to set color: %s (%d)", mName.string(), - to_string(error).c_str(), static_cast(error)); + ALOGE("[%s] Failed to set color: %s (%d)", mName.string(), to_string(error).c_str(), + static_cast(error)); } // Clear out the transform, because it doesn't make sense absent a @@ -773,7 +752,7 @@ void Layer::setPerFrameData(const sp& displayDevice) { error = hwcLayer->setTransform(HWC2::Transform::None); if (error != HWC2::Error::None) { ALOGE("[%s] Failed to clear transform: %s (%d)", mName.string(), - to_string(error).c_str(), static_cast(error)); + to_string(error).c_str(), static_cast(error)); } return; @@ -791,28 +770,25 @@ void Layer::setPerFrameData(const sp& displayDevice) { ALOGV("setPerFrameData: dataspace = %d", mCurrentState.dataSpace); error = hwcLayer->setDataspace(mCurrentState.dataSpace); if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), - mCurrentState.dataSpace, to_string(error).c_str(), - static_cast(error)); + ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), mCurrentState.dataSpace, + to_string(error).c_str(), static_cast(error)); } uint32_t hwcSlot = 0; sp hwcBuffer; - hwcInfo.bufferCache.getHwcBuffer(mActiveBufferSlot, mActiveBuffer, - &hwcSlot, &hwcBuffer); + hwcInfo.bufferCache.getHwcBuffer(mActiveBufferSlot, mActiveBuffer, &hwcSlot, &hwcBuffer); auto acquireFence = mSurfaceFlingerConsumer->getCurrentFence(); error = hwcLayer->setBuffer(hwcSlot, hwcBuffer, acquireFence); if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(), - mActiveBuffer->handle, to_string(error).c_str(), - static_cast(error)); + ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(), mActiveBuffer->handle, + to_string(error).c_str(), static_cast(error)); } } #else void Layer::setPerFrameData(const sp& hw, - HWComposer::HWCLayerInterface& layer) { + HWComposer::HWCLayerInterface& layer) { // we have to set the visible region on every frame because // we currently free it during onLayerDisplayed(), which is called // after HWComposer::commit() -- every frame. @@ -837,8 +813,7 @@ void Layer::setPerFrameData(const sp& hw, #ifdef USE_HWC2 void Layer::updateCursorPosition(const sp& displayDevice) { auto hwcId = displayDevice->getHwcDisplayId(); - if (mHwcLayers.count(hwcId) == 0 || - getCompositionType(hwcId) != HWC2::Composition::Cursor) { + if (mHwcLayers.count(hwcId) == 0 || getCompositionType(hwcId) != HWC2::Composition::Cursor) { return; } @@ -861,22 +836,23 @@ void Layer::updateCursorPosition(const sp& displayDevice) { auto& displayTransform(displayDevice->getTransform()); auto position = displayTransform.transform(frame); - auto error = mHwcLayers[hwcId].layer->setCursorPosition(position.left, - position.top); - ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set cursor position " - "to (%d, %d): %s (%d)", mName.string(), position.left, - position.top, to_string(error).c_str(), - static_cast(error)); + auto error = mHwcLayers[hwcId].layer->setCursorPosition(position.left, position.top); + ALOGE_IF(error != HWC2::Error::None, + "[%s] Failed to set cursor position " + "to (%d, %d): %s (%d)", + mName.string(), position.left, position.top, to_string(error).c_str(), + static_cast(error)); } #else void Layer::setAcquireFence(const sp& /* hw */, - HWComposer::HWCLayerInterface& layer) { + HWComposer::HWCLayerInterface& layer) { int fenceFd = -1; // TODO: there is a possible optimization here: we only need to set the // acquire fence the first time a new buffer is acquired on EACH display. - if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) { + if (layer.getCompositionType() == HWC_OVERLAY || + layer.getCompositionType() == HWC_CURSOR_OVERLAY) { sp fence = mSurfaceFlingerConsumer->getCurrentFence(); if (fence->isValid()) { fenceFd = fence->dup(); @@ -888,9 +864,7 @@ void Layer::setAcquireFence(const sp& /* hw */, layer.setAcquireFenceFd(fenceFd); } -Rect Layer::getPosition( - const sp& hw) -{ +Rect Layer::getPosition(const sp& hw) { // this gives us only the "orientation" component of the transform const State& s(getCurrentState()); @@ -928,10 +902,8 @@ void Layer::draw(const RenderArea& renderArea) const { onDraw(renderArea, Region(renderArea.getBounds()), false); } -void Layer::clearWithOpenGL(const RenderArea& renderArea, - float red, float green, float blue, - float alpha) const -{ +void Layer::clearWithOpenGL(const RenderArea& renderArea, float red, float green, float blue, + float alpha) const { RenderEngine& engine(mFlinger->getRenderEngine()); computeGeometry(renderArea, mMesh, false); engine.setupFillWithColor(red, green, blue, alpha); @@ -939,29 +911,29 @@ void Layer::clearWithOpenGL(const RenderArea& renderArea, } void Layer::clearWithOpenGL(const RenderArea& renderArea) const { - clearWithOpenGL(renderArea, 0,0,0,0); + clearWithOpenGL(renderArea, 0, 0, 0, 0); } #ifdef USE_HWC2 -void Layer::setCompositionType(int32_t hwcId, HWC2::Composition type, - bool callIntoHwc) { +void Layer::setCompositionType(int32_t hwcId, HWC2::Composition type, bool callIntoHwc) { if (mHwcLayers.count(hwcId) == 0) { ALOGE("setCompositionType called without a valid HWC layer"); return; } auto& hwcInfo = mHwcLayers[hwcId]; auto& hwcLayer = hwcInfo.layer; - ALOGV("setCompositionType(%" PRIx64 ", %s, %d)", hwcLayer->getId(), - to_string(type).c_str(), static_cast(callIntoHwc)); + ALOGV("setCompositionType(%" PRIx64 ", %s, %d)", hwcLayer->getId(), to_string(type).c_str(), + static_cast(callIntoHwc)); if (hwcInfo.compositionType != type) { ALOGV(" actually setting"); hwcInfo.compositionType = type; if (callIntoHwc) { auto error = hwcLayer->setCompositionType(type); - ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set " - "composition type %s: %s (%d)", mName.string(), - to_string(type).c_str(), to_string(error).c_str(), - static_cast(error)); + ALOGE_IF(error != HWC2::Error::None, + "[%s] Failed to set " + "composition type %s: %s (%d)", + mName.string(), to_string(type).c_str(), to_string(error).c_str(), + static_cast(error)); } } } @@ -1067,13 +1039,12 @@ void Layer::computeGeometry(const RenderArea& renderArea, Mesh& mesh, position[1] = renderAreaTransform.transform(lb); position[2] = renderAreaTransform.transform(rb); position[3] = renderAreaTransform.transform(rt); - for (size_t i=0 ; i<4 ; i++) { + for (size_t i = 0; i < 4; i++) { position[i].y = height - position[i].y; } } -bool Layer::isSecure() const -{ +bool Layer::isSecure() const { const Layer::State& s(mDrawingState); return (s.flags & layer_state_t::eLayerSecure); } @@ -1088,8 +1059,7 @@ void Layer::setCoveredRegion(const Region& coveredRegion) { this->coveredRegion = coveredRegion; } -void Layer::setVisibleNonTransparentRegion(const Region& - setVisibleNonTransparentRegion) { +void Layer::setVisibleNonTransparentRegion(const Region& setVisibleNonTransparentRegion) { // always called from main thread this->visibleNonTransparentRegion = setVisibleNonTransparentRegion; } @@ -1114,8 +1084,7 @@ void Layer::pushPendingState() { // to be applied as per normal (no synchronization). mCurrentState.barrierLayer = nullptr; } else { - auto syncPoint = std::make_shared( - mCurrentState.frameNumber); + auto syncPoint = std::make_shared(mCurrentState.frameNumber); if (barrierLayer->addSyncPoint(syncPoint)) { mRemoteSyncPoints.push_back(std::move(syncPoint)); } else { @@ -1136,8 +1105,8 @@ void Layer::pushPendingState() { void Layer::popPendingState(State* stateToCommit) { auto oldFlags = stateToCommit->flags; *stateToCommit = mPendingStates[0]; - stateToCommit->flags = (oldFlags & ~stateToCommit->mask) | - (stateToCommit->flags & stateToCommit->mask); + stateToCommit->flags = + (oldFlags & ~stateToCommit->mask) | (stateToCommit->flags & stateToCommit->mask); mPendingStates.removeAt(0); ATRACE_INT(mTransactionName.string(), mPendingStates.size()); @@ -1157,10 +1126,8 @@ bool Layer::applyPendingStates(State* stateToCommit) { continue; } - if (mRemoteSyncPoints.front()->getFrameNumber() != - mPendingStates[0].frameNumber) { - ALOGE("[%s] Unexpected sync point frame number found", - mName.string()); + if (mRemoteSyncPoints.front()->getFrameNumber() != mPendingStates[0].frameNumber) { + ALOGE("[%s] Unexpected sync point frame number found", mName.string()); // Signal our end of the sync point and then dispose of it mRemoteSyncPoints.front()->setTransactionApplied(); @@ -1207,40 +1174,25 @@ uint32_t Layer::doTransaction(uint32_t flags) { const Layer::State& s(getDrawingState()); - const bool sizeChanged = (c.requested.w != s.requested.w) || - (c.requested.h != s.requested.h); + const bool sizeChanged = (c.requested.w != s.requested.w) || (c.requested.h != s.requested.h); if (mSurfaceFlingerConsumer && sizeChanged) { // the size changed, we need to ask our client to request a new buffer ALOGD_IF(DEBUG_RESIZE, - "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n" - " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" - " requested={ wh={%4u,%4u} }}\n" - " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" - " requested={ wh={%4u,%4u} }}\n", - this, getName().string(), mCurrentTransform, - getEffectiveScalingMode(), - c.active.w, c.active.h, - c.crop.left, - c.crop.top, - c.crop.right, - c.crop.bottom, - c.crop.getWidth(), - c.crop.getHeight(), - c.requested.w, c.requested.h, - s.active.w, s.active.h, - s.crop.left, - s.crop.top, - s.crop.right, - s.crop.bottom, - s.crop.getWidth(), - s.crop.getHeight(), - s.requested.w, s.requested.h); + "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n" + " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" + " requested={ wh={%4u,%4u} }}\n" + " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" + " requested={ wh={%4u,%4u} }}\n", + this, getName().string(), mCurrentTransform, getEffectiveScalingMode(), c.active.w, + c.active.h, c.crop.left, c.crop.top, c.crop.right, c.crop.bottom, + c.crop.getWidth(), c.crop.getHeight(), c.requested.w, c.requested.h, s.active.w, + s.active.h, s.crop.left, s.crop.top, s.crop.right, s.crop.bottom, + s.crop.getWidth(), s.crop.getHeight(), s.requested.w, s.requested.h); // record the new size, form this point on, when the client request // a buffer, it'll get the new size. - mSurfaceFlingerConsumer->setDefaultBufferSize( - c.requested.w, c.requested.h); + mSurfaceFlingerConsumer->setDefaultBufferSize(c.requested.w, c.requested.h); } // Don't let Layer::doTransaction update the drawing state @@ -1261,8 +1213,8 @@ uint32_t Layer::doTransaction(uint32_t flags) { // resizePending state is to avoid applying the state of the new buffer // to the old buffer. However in the state where we don't have an old buffer // there is no such concern but we may still be being used as a parent layer. - const bool resizePending = ((c.requested.w != c.active.w) || - (c.requested.h != c.active.h)) && (mActiveBuffer != nullptr); + const bool resizePending = ((c.requested.w != c.active.w) || (c.requested.h != c.active.h)) && + (mActiveBuffer != nullptr); if (!isFixedSize()) { if (resizePending && mSidebandStream == NULL) { flags |= eDontUpdateGeometryState; @@ -1311,8 +1263,7 @@ uint32_t Layer::doTransaction(uint32_t flags) { // we may use linear filtering, if the matrix scales us const uint8_t type = c.active.transform.getType(); - mNeedsFiltering = (!c.active.transform.preserveRects() || - (type >= Transform::SCALE)); + mNeedsFiltering = (!c.active.transform.preserveRects() || (type >= Transform::SCALE)); } // If the layer is hidden, signal and clear out all local sync points so @@ -1375,8 +1326,7 @@ bool Layer::setChildLayer(const sp& childLayer, int32_t z) { } bool Layer::setLayer(int32_t z) { - if (mCurrentState.z == z) - return false; + if (mCurrentState.z == z) return false; mCurrentState.sequence++; mCurrentState.z = z; mCurrentState.modified = true; @@ -1434,8 +1384,7 @@ bool Layer::setRelativeLayer(const sp& relativeToHandle, int32_t z) { } bool Layer::setSize(uint32_t w, uint32_t h) { - if (mCurrentState.requested.w == w && mCurrentState.requested.h == h) - return false; + if (mCurrentState.requested.w == w && mCurrentState.requested.h == h) return false; mCurrentState.requested.w = w; mCurrentState.requested.h = h; mCurrentState.modified = true; @@ -1443,8 +1392,7 @@ bool Layer::setSize(uint32_t w, uint32_t h) { return true; } bool Layer::setAlpha(float alpha) { - if (mCurrentState.color.a == alpha) - return false; + if (mCurrentState.color.a == alpha) return false; mCurrentState.sequence++; mCurrentState.color.a = alpha; mCurrentState.modified = true; @@ -1453,8 +1401,8 @@ bool Layer::setAlpha(float alpha) { } bool Layer::setColor(const half3& color) { - if (color.r == mCurrentState.color.r && color.g == mCurrentState.color.g - && color.b == mCurrentState.color.b) + if (color.r == mCurrentState.color.r && color.g == mCurrentState.color.g && + color.b == mCurrentState.color.b) return false; mCurrentState.sequence++; @@ -1468,8 +1416,7 @@ bool Layer::setColor(const half3& color) { bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) { mCurrentState.sequence++; - mCurrentState.requested.transform.set( - matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy); + mCurrentState.requested.transform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy); mCurrentState.modified = true; setTransactionFlags(eTransactionNeeded); return true; @@ -1482,8 +1429,7 @@ bool Layer::setTransparentRegionHint(const Region& transparent) { } bool Layer::setFlags(uint8_t flags, uint8_t mask) { const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask); - if (mCurrentState.flags == newFlags) - return false; + if (mCurrentState.flags == newFlags) return false; mCurrentState.sequence++; mCurrentState.flags = newFlags; mCurrentState.mask = mask; @@ -1493,8 +1439,7 @@ bool Layer::setFlags(uint8_t flags, uint8_t mask) { } bool Layer::setCrop(const Rect& crop, bool immediate) { - if (mCurrentState.requestedCrop == crop) - return false; + if (mCurrentState.requestedCrop == crop) return false; mCurrentState.sequence++; mCurrentState.requestedCrop = crop; if (immediate && !mFreezeGeometryUpdates) { @@ -1508,8 +1453,7 @@ bool Layer::setCrop(const Rect& crop, bool immediate) { } bool Layer::setFinalCrop(const Rect& crop, bool immediate) { - if (mCurrentState.requestedFinalCrop == crop) - return false; + if (mCurrentState.requestedFinalCrop == crop) return false; mCurrentState.sequence++; mCurrentState.requestedFinalCrop = crop; if (immediate && !mFreezeGeometryUpdates) { @@ -1523,23 +1467,21 @@ bool Layer::setFinalCrop(const Rect& crop, bool immediate) { } bool Layer::setOverrideScalingMode(int32_t scalingMode) { - if (scalingMode == mOverrideScalingMode) - return false; + if (scalingMode == mOverrideScalingMode) return false; mOverrideScalingMode = scalingMode; setTransactionFlags(eTransactionNeeded); return true; } void Layer::setInfo(uint32_t type, uint32_t appId) { - mCurrentState.appId = appId; - mCurrentState.type = type; - mCurrentState.modified = true; - setTransactionFlags(eTransactionNeeded); + mCurrentState.appId = appId; + mCurrentState.type = type; + mCurrentState.modified = true; + setTransactionFlags(eTransactionNeeded); } bool Layer::setLayerStack(uint32_t layerStack) { - if (mCurrentState.layerStack == layerStack) - return false; + if (mCurrentState.layerStack == layerStack) return false; mCurrentState.sequence++; mCurrentState.layerStack = layerStack; mCurrentState.modified = true; @@ -1548,8 +1490,7 @@ bool Layer::setLayerStack(uint32_t layerStack) { } bool Layer::setDataSpace(android_dataspace dataSpace) { - if (mCurrentState.dataSpace == dataSpace) - return false; + if (mCurrentState.dataSpace == dataSpace) return false; mCurrentState.sequence++; mCurrentState.dataSpace = dataSpace; mCurrentState.modified = true; @@ -1569,8 +1510,7 @@ uint32_t Layer::getLayerStack() const { return p->getLayerStack(); } -void Layer::deferTransactionUntil(const sp& barrierLayer, - uint64_t frameNumber) { +void Layer::deferTransactionUntil(const sp& barrierLayer, uint64_t frameNumber) { mCurrentState.barrierLayer = barrierLayer; mCurrentState.frameNumber = frameNumber; // We don't set eTransactionNeeded, because just receiving a deferral @@ -1582,8 +1522,7 @@ void Layer::deferTransactionUntil(const sp& barrierLayer, mCurrentState.modified = false; } -void Layer::deferTransactionUntil(const sp& barrierHandle, - uint64_t frameNumber) { +void Layer::deferTransactionUntil(const sp& barrierHandle, uint64_t frameNumber) { sp handle = static_cast(barrierHandle.get()); deferTransactionUntil(handle->owner.promote(), frameNumber); } @@ -1614,40 +1553,38 @@ bool Layer::shouldPresentNow(const DispSync& dispSync) const { return false; } auto timestamp = mQueueItems[0].mTimestamp; - nsecs_t expectedPresent = - mSurfaceFlingerConsumer->computeExpectedPresent(dispSync); + nsecs_t expectedPresent = mSurfaceFlingerConsumer->computeExpectedPresent(dispSync); // Ignore timestamps more than a second in the future bool isPlausible = timestamp < (expectedPresent + s2ns(1)); - ALOGW_IF(!isPlausible, "[%s] Timestamp %" PRId64 " seems implausible " - "relative to expectedPresent %" PRId64, mName.string(), timestamp, - expectedPresent); + ALOGW_IF(!isPlausible, + "[%s] Timestamp %" PRId64 " seems implausible " + "relative to expectedPresent %" PRId64, + mName.string(), timestamp, expectedPresent); bool isDue = timestamp < expectedPresent; return isDue || !isPlausible; } bool Layer::onPostComposition(const std::shared_ptr& glDoneFence, - const std::shared_ptr& presentFence, - const CompositorTiming& compositorTiming) { + const std::shared_ptr& presentFence, + const CompositorTiming& compositorTiming) { // mFrameLatencyNeeded is true when a new frame was latched for the // composition. - if (!mFrameLatencyNeeded) - return false; + if (!mFrameLatencyNeeded) return false; // Update mFrameEventHistory. { Mutex::Autolock lock(mFrameEventHistoryMutex); - mFrameEventHistory.addPostComposition(mCurrentFrameNumber, - glDoneFence, presentFence, compositorTiming); + mFrameEventHistory.addPostComposition(mCurrentFrameNumber, glDoneFence, presentFence, + compositorTiming); } // Update mFrameTracker. nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp(); mFrameTracker.setDesiredPresentTime(desiredPresentTime); - std::shared_ptr frameReadyFence = - mSurfaceFlingerConsumer->getCurrentFenceTime(); + std::shared_ptr frameReadyFence = mSurfaceFlingerConsumer->getCurrentFenceTime(); if (frameReadyFence->isValid()) { mFrameTracker.setFrameReadyFence(std::move(frameReadyFence)); } else { @@ -1657,14 +1594,12 @@ bool Layer::onPostComposition(const std::shared_ptr& glDoneFence, } if (presentFence->isValid()) { - mFrameTracker.setActualPresentFence( - std::shared_ptr(presentFence)); + mFrameTracker.setActualPresentFence(std::shared_ptr(presentFence)); } else { // The HWC doesn't support present fences, so use the refresh // timestamp instead. mFrameTracker.setActualPresentTime( - mFlinger->getHwComposer().getRefreshTimestamp( - HWC_DISPLAY_PRIMARY)); + mFlinger->getHwComposer().getRefreshTimestamp(HWC_DISPLAY_PRIMARY)); } mFrameTracker.advanceFrame(); @@ -1681,8 +1616,7 @@ bool Layer::isHiddenByPolicy() const { return s.flags & layer_state_t::eLayerHidden; } -uint32_t Layer::getEffectiveUsage(uint32_t usage) const -{ +uint32_t Layer::getEffectiveUsage(uint32_t usage) const { // TODO: should we do something special if mSecure is set? if (mProtectedByApp) { // need a hardware-protected path to external video sink @@ -1796,14 +1730,11 @@ void Layer::miniDump(String8& result, int32_t hwcId) const { const Layer::State& layerState(getDrawingState()); const HWCInfo& hwcInfo = mHwcLayers.at(hwcId); result.appendFormat(" %10d | ", layerState.z); - result.appendFormat("%10s | ", - to_string(getCompositionType(hwcId)).c_str()); + result.appendFormat("%10s | ", to_string(getCompositionType(hwcId)).c_str()); const Rect& frame = hwcInfo.displayFrame; - result.appendFormat("%4d %4d %4d %4d | ", frame.left, frame.top, - frame.right, frame.bottom); + result.appendFormat("%4d %4d %4d %4d | ", frame.left, frame.top, frame.right, frame.bottom); 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.appendFormat("%6.1f %6.1f %6.1f %6.1f\n", crop.left, crop.top, crop.right, crop.bottom); result.append("- - - - - - - - - - - - - - - - - - - - "); result.append("- - - - - - - - - - - - - - - - - - - -\n"); @@ -1827,8 +1758,7 @@ void Layer::getFrameStats(FrameStats* outStats) const { } void Layer::dumpFrameEvents(String8& result) { - result.appendFormat("- Layer %s (%s, %p)\n", - getName().string(), getTypeId(), this); + result.appendFormat("- Layer %s (%s, %p)\n", getName().string(), getTypeId(), this); Mutex::Autolock lock(mFrameEventHistoryMutex); mFrameEventHistory.checkFencesForCompletion(); mFrameEventHistory.dump(result); @@ -1840,7 +1770,7 @@ void Layer::onDisconnect() { } void Layer::addAndGetFrameTimestamps(const NewFrameEventsEntry* newTimestamps, - FrameEventHistoryDelta *outDelta) { + FrameEventHistoryDelta* outDelta) { Mutex::Autolock lock(mFrameEventHistoryMutex); if (newTimestamps) { // If there are any unsignaled fences in the aquire timeline at this @@ -1858,18 +1788,14 @@ void Layer::addAndGetFrameTimestamps(const NewFrameEventsEntry* newTimestamps, } } -std::vector Layer::getOccupancyHistory( - bool forceFlush) { +std::vector Layer::getOccupancyHistory(bool forceFlush) { std::vector history; - if (!mSurfaceFlingerConsumer) - return {}; + if (!mSurfaceFlingerConsumer) return {}; - status_t result = mSurfaceFlingerConsumer->getOccupancyHistory(forceFlush, - &history); + status_t result = mSurfaceFlingerConsumer->getOccupancyHistory(forceFlush, &history); if (result != NO_ERROR) { - ALOGW("[%s] Failed to obtain occupancy history (%d)", mName.string(), - result); + ALOGW("[%s] Failed to obtain occupancy history (%d)", mName.string(), result); return {}; } return history; @@ -1990,8 +1916,8 @@ int32_t Layer::getZ() const { return mDrawingState.z; } -__attribute__((no_sanitize("unsigned-integer-overflow"))) -LayerVector Layer::makeTraversalList(LayerVector::StateSet stateSet) { +__attribute__((no_sanitize("unsigned-integer-overflow"))) LayerVector Layer::makeTraversalList( + LayerVector::StateSet stateSet) { LOG_ALWAYS_FATAL_IF(stateSet == LayerVector::StateSet::Invalid, "makeTraversalList received invalid stateSet"); const bool useDrawing = stateSet == LayerVector::StateSet::Drawing; @@ -2046,7 +1972,7 @@ void Layer::traverseInReverseZOrder(LayerVector::StateSet stateSet, LayerVector list = makeTraversalList(stateSet); int32_t i = 0; - for (i = list.size()-1; i>=0; i--) { + for (i = list.size() - 1; i >= 0; i--) { const auto& relative = list[i]; if (relative->getZ() < 0) { break; @@ -2054,7 +1980,7 @@ void Layer::traverseInReverseZOrder(LayerVector::StateSet stateSet, relative->traverseInReverseZOrder(stateSet, visitor); } visitor(this); - for (; i>=0; i--) { + for (; i >= 0; i--) { const auto& relative = list[i]; relative->traverseInReverseZOrder(stateSet, visitor); } @@ -2104,10 +2030,8 @@ Transform Layer::getTransform() const { bufferHeight = p->mActiveBuffer->getWidth(); bufferWidth = p->mActiveBuffer->getHeight(); } - float sx = p->getDrawingState().active.w / - static_cast(bufferWidth); - float sy = p->getDrawingState().active.h / - static_cast(bufferHeight); + float sx = p->getDrawingState().active.w / static_cast(bufferWidth); + float sy = p->getDrawingState().active.h / static_cast(bufferHeight); Transform extraParentScaling; extraParentScaling.set(sx, 0, 0, sy); t = t * extraParentScaling; diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index ee3bb7ef3f..db94a31c5e 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -37,20 +37,20 @@ #include -#include "FrameTracker.h" #include "Client.h" +#include "FrameTracker.h" #include "LayerVector.h" #include "MonitoredProducer.h" #include "SurfaceFlinger.h" #include "SurfaceFlingerConsumer.h" #include "Transform.h" +#include #include "DisplayHardware/HWComposer.h" #include "DisplayHardware/HWComposerBufferCache.h" +#include "RenderArea.h" #include "RenderEngine/Mesh.h" #include "RenderEngine/Texture.h" -#include -#include "RenderArea.h" #include @@ -69,8 +69,7 @@ class LayerDebugInfo; // --------------------------------------------------------------------------- -class Layer : public virtual RefBase -{ +class Layer : public virtual RefBase { static int32_t sSequence; public: @@ -96,14 +95,11 @@ public: uint32_t h; Transform transform; - inline bool operator ==(const Geometry& rhs) const { - return (w == rhs.w && h == rhs.h) && - (transform.tx() == rhs.transform.tx()) && + inline bool operator==(const Geometry& rhs) const { + return (w == rhs.w && h == rhs.h) && (transform.tx() == rhs.transform.tx()) && (transform.ty() == rhs.transform.ty()); } - inline bool operator !=(const Geometry& rhs) const { - return !operator ==(rhs); - } + inline bool operator!=(const Geometry& rhs) const { return !operator==(rhs); } }; struct State { @@ -156,8 +152,8 @@ public: half4 color; }; - Layer(SurfaceFlinger* flinger, const sp& client, - const String8& name, uint32_t w, uint32_t h, uint32_t flags); + Layer(SurfaceFlinger* flinger, const sp& client, const String8& name, uint32_t w, + uint32_t h, uint32_t flags); virtual ~Layer(); void setPrimaryDisplayOnly() { mPrimaryDisplayOnly = true; } @@ -287,7 +283,8 @@ public: */ virtual bool isFixedSize() const = 0; - void writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet = LayerVector::StateSet::Drawing); + void writeToProto(LayerProto* layerInfo, + LayerVector::StateSet stateSet = LayerVector::StateSet::Drawing); protected: /* @@ -310,8 +307,7 @@ public: bool getClearClientTarget(int32_t hwcId) const; void updateCursorPosition(const sp& hw); #else - void setGeometry(const sp& hw, - HWComposer::HWCLayerInterface& layer); + void setGeometry(const sp& hw, HWComposer::HWCLayerInterface& layer); void setPerFrameData(const sp& hw, HWComposer::HWCLayerInterface& layer); void setAcquireFence(const sp& hw, HWComposer::HWCLayerInterface& layer); @@ -324,8 +320,7 @@ public: #ifdef USE_HWC2 void onLayerDisplayed(const sp& releaseFence); #else - void onLayerDisplayed(const sp& hw, - HWComposer::HWCLayerInterface* layer); + void onLayerDisplayed(const sp& hw, HWComposer::HWCLayerInterface* layer); #endif bool shouldPresentNow(const DispSync& dispSync) const; @@ -341,8 +336,8 @@ public: * returns true if the layer latched a new buffer this frame. */ bool onPostComposition(const std::shared_ptr& glDoneFence, - const std::shared_ptr& presentFence, - const CompositorTiming& compositorTiming); + const std::shared_ptr& presentFence, + const CompositorTiming& compositorTiming); #ifdef USE_HWC2 // If a buffer was replaced this frame, release the former buffer @@ -380,8 +375,7 @@ public: * setVisibleNonTransparentRegion - called when the visible and * non-transparent region changes. */ - void setVisibleNonTransparentRegion(const Region& - visibleNonTransparentRegion); + void setVisibleNonTransparentRegion(const Region& visibleNonTransparentRegion); /* * latchBuffer - called each time the screen is redrawn and returns whether @@ -405,7 +399,6 @@ public: */ void onRemoved(); - // Updates the transform hint in our SurfaceFlingerConsumer to match // the current orientation of the display device. void updateTransformHint(const sp& hw) const; @@ -419,8 +412,9 @@ public: /* * Returns if a frame is queued. */ - bool hasQueuedFrame() const { return mQueuedFrames > 0 || - mSidebandStreamChanged || mAutoRefresh; } + bool hasQueuedFrame() const { + return mQueuedFrames > 0 || mSidebandStreamChanged || mAutoRefresh; + } int32_t getQueuedFrameCount() const { return mQueuedFrames; } @@ -431,9 +425,7 @@ public: void destroyHwcLayer(int32_t hwcId); void destroyAllHwcLayers(); - bool hasHwcLayer(int32_t hwcId) { - return mHwcLayers.count(hwcId) > 0; - } + bool hasHwcLayer(int32_t hwcId) { return mHwcLayers.count(hwcId) > 0; } HWC2::Layer* getHwcLayer(int32_t hwcId) { if (mHwcLayers.count(hwcId) == 0) { @@ -452,9 +444,9 @@ public: // only for debugging inline const sp& getActiveBuffer() const { return mActiveBuffer; } - inline const State& getDrawingState() const { return mDrawingState; } - inline const State& getCurrentState() const { return mCurrentState; } - inline State& getCurrentState() { return mCurrentState; } + inline const State& getDrawingState() const { return mDrawingState; } + inline const State& getCurrentState() const { return mCurrentState; } + inline State& getCurrentState() { return mCurrentState; } LayerDebugInfo getLayerDebugInfo() const; @@ -473,7 +465,7 @@ public: void onDisconnect(); void addAndGetFrameTimestamps(const NewFrameEventsEntry* newEntry, - FrameEventHistoryDelta* outDelta); + FrameEventHistoryDelta* outDelta); bool getTransformToDisplayInverse() const; @@ -506,6 +498,7 @@ public: // SurfaceFlinger to complete a transaction. void commitChildList(); int32_t getZ() const; + protected: // constant sp mFlinger; @@ -516,23 +509,20 @@ protected: class LayerCleaner { sp mFlinger; wp mLayer; + protected: ~LayerCleaner() { // destroy client resources mFlinger->onLayerDestroyed(mLayer); } + public: - LayerCleaner(const sp& flinger, - const sp& layer) - : mFlinger(flinger), mLayer(layer) { - } + LayerCleaner(const sp& flinger, const sp& layer) + : mFlinger(flinger), mLayer(layer) {} }; - virtual void onFirstRef(); - - friend class SurfaceInterceptor; void commitTransaction(const State& stateToCommit); @@ -546,8 +536,8 @@ protected: Rect computeInitialCrop(const sp& hw) const; // drawing - void clearWithOpenGL(const RenderArea& renderArea, - float r, float g, float b, float alpha) const; + void clearWithOpenGL(const RenderArea& renderArea, float r, float g, float b, + float alpha) const; void setParent(const sp& layer); @@ -556,31 +546,20 @@ protected: void removeZOrderRelative(const wp& relative); protected: - class SyncPoint - { + class SyncPoint { public: - explicit SyncPoint(uint64_t frameNumber) : mFrameNumber(frameNumber), - mFrameIsAvailable(false), mTransactionIsApplied(false) {} + explicit SyncPoint(uint64_t frameNumber) + : mFrameNumber(frameNumber), mFrameIsAvailable(false), mTransactionIsApplied(false) {} - uint64_t getFrameNumber() const { - return mFrameNumber; - } + uint64_t getFrameNumber() const { return mFrameNumber; } - bool frameIsAvailable() const { - return mFrameIsAvailable; - } + bool frameIsAvailable() const { return mFrameIsAvailable; } - void setFrameAvailable() { - mFrameIsAvailable = true; - } + void setFrameAvailable() { mFrameIsAvailable = true; } - bool transactionIsApplied() const { - return mTransactionIsApplied; - } + bool transactionIsApplied() const { return mTransactionIsApplied; } - void setTransactionApplied() { - mTransactionIsApplied = true; - } + void setTransactionApplied() { mTransactionIsApplied = true; } private: const uint64_t mFrameNumber; @@ -611,6 +590,7 @@ protected: // Client) or mOverrideScalingMode mode (originating from // the Surface Controller) if set. virtual uint32_t getEffectiveScalingMode() const = 0; + public: /* * The layer handle is just a BBinder object passed to the client @@ -621,11 +601,11 @@ public: * this layer when the handle is destroyed. */ class Handle : public BBinder, public LayerCleaner { - public: - Handle(const sp& flinger, const sp& layer) - : LayerCleaner(flinger, layer), owner(layer) {} + public: + Handle(const sp& flinger, const sp& layer) + : LayerCleaner(flinger, layer), owner(layer) {} - wp owner; + wp owner; }; sp getHandle(); @@ -633,15 +613,15 @@ public: virtual void notifyAvailableFrames() = 0; virtual PixelFormat getPixelFormat() const = 0; bool getPremultipledAlpha() const; -protected: +protected: // ----------------------------------------------------------------------- // constants sp mSurfaceFlingerConsumer; bool mPremultipliedAlpha; String8 mName; - String8 mTransactionName; // A cached version of "TX - " + mName for systraces + String8 mTransactionName; // A cached version of "TX - " + mName for systraces bool mPrimaryDisplayOnly = false; @@ -656,7 +636,7 @@ protected: // thread-safe volatile int32_t mQueuedFrames; - volatile int32_t mSidebandStreamChanged; // used like an atomic boolean + volatile int32_t mSidebandStreamChanged; // used like an atomic boolean // Timestamp history for UIAutomation. Thread safe. FrameTracker mFrameTracker; @@ -686,16 +666,15 @@ protected: // The mesh used to draw the layer in GLES composition mode mutable Mesh mMesh; - #ifdef USE_HWC2 // HWC items, accessed from the main thread struct HWCInfo { HWCInfo() - : hwc(nullptr), - layer(nullptr), - forceClientComposition(false), - compositionType(HWC2::Composition::Invalid), - clearClientTarget(false) {} + : hwc(nullptr), + layer(nullptr), + forceClientComposition(false), + compositionType(HWC2::Composition::Invalid), + clearClientTarget(false) {} HWComposer* hwc; HWC2::Layer* layer; -- cgit v1.2.3-59-g8ed1b From eb085e0c579f310e2670204b14b742b68c70bc9e Mon Sep 17 00:00:00 2001 From: David Sodman Date: Thu, 5 Oct 2017 18:49:04 -0700 Subject: Move mSurfaceFlingerConsumer into BufferLayer One of the benefits of splitting the Layer class to have the BufferLayer specific derived class is so that the SurfaceFlingerConsumer can be completely removed from the ColorLayer class (which has no BufferQueue). This change implements that change. Test: Transaction_test.cpp and manual test Change-Id: Ia923c3e0ea366f58de61eca31b444b3332a23e51 --- services/surfaceflinger/BufferLayer.cpp | 175 ++++++++++++++++------ services/surfaceflinger/BufferLayer.h | 33 ++++- services/surfaceflinger/ColorLayer.cpp | 30 ++++ services/surfaceflinger/ColorLayer.h | 21 +++ services/surfaceflinger/Layer.cpp | 248 ++------------------------------ services/surfaceflinger/Layer.h | 37 ++--- 6 files changed, 249 insertions(+), 295 deletions(-) (limited to 'services/surfaceflinger/BufferLayer.cpp') diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index 8f5dea2691..45093be1a3 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -53,6 +53,7 @@ namespace android { BufferLayer::BufferLayer(SurfaceFlinger* flinger, const sp& client, const String8& name, uint32_t w, uint32_t h, uint32_t flags) : Layer(flinger, client, name, w, h, flags), + mSurfaceFlingerConsumer(nullptr), mTextureName(-1U), mFormat(PIXEL_FORMAT_NONE), mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), @@ -99,6 +100,18 @@ BufferLayer::~BufferLayer() { #endif } +void BufferLayer::useSurfaceDamage() { + if (mFlinger->mForceFullDamage) { + surfaceDamageRegion = Region::INVALID_REGION; + } else { + surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage(); + } +} + +void BufferLayer::useEmptyDamage() { + surfaceDamageRegion.clear(); +} + bool BufferLayer::isProtected() const { const sp& activeBuffer(mActiveBuffer); return (activeBuffer != 0) && (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED); @@ -252,6 +265,54 @@ void BufferLayer::onDraw(const RenderArea& renderArea, const Region& clip, engine.disableTexturing(); } +#ifdef USE_HWC2 +void BufferLayer::onLayerDisplayed(const sp& releaseFence) { + if (mHwcLayers.empty()) { + return; + } + mSurfaceFlingerConsumer->setReleaseFence(releaseFence); +} +#else +void BufferLayer::onLayerDisplayed(const sp& /*hw*/, + HWComposer::HWCLayerInterface* layer) { + if (layer) { + layer->onDisplayed(); + mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence()); + } +} +#endif + +void BufferLayer::abandon() { + mSurfaceFlingerConsumer->abandon(); +} + +bool BufferLayer::shouldPresentNow(const DispSync& dispSync) const { + if (mSidebandStreamChanged || mAutoRefresh) { + return true; + } + + Mutex::Autolock lock(mQueueItemLock); + if (mQueueItems.empty()) { + return false; + } + auto timestamp = mQueueItems[0].mTimestamp; + nsecs_t expectedPresent = mSurfaceFlingerConsumer->computeExpectedPresent(dispSync); + + // Ignore timestamps more than a second in the future + bool isPlausible = timestamp < (expectedPresent + s2ns(1)); + ALOGW_IF(!isPlausible, + "[%s] Timestamp %" PRId64 " seems implausible " + "relative to expectedPresent %" PRId64, + mName.string(), timestamp, expectedPresent); + + bool isDue = timestamp < expectedPresent; + return isDue || !isPlausible; +} + +void BufferLayer::setTransformHint(uint32_t orientation) const { + mSurfaceFlingerConsumer->setTransformHint(orientation); +} + bool BufferLayer::onPreComposition(nsecs_t refreshStartTime) { if (mBufferLatched) { Mutex::Autolock lock(mFrameEventHistoryMutex); @@ -260,6 +321,60 @@ bool BufferLayer::onPreComposition(nsecs_t refreshStartTime) { mRefreshPending = false; return mQueuedFrames > 0 || mSidebandStreamChanged || mAutoRefresh; } +bool BufferLayer::onPostComposition(const std::shared_ptr& glDoneFence, + const std::shared_ptr& presentFence, + const CompositorTiming& compositorTiming) { + // mFrameLatencyNeeded is true when a new frame was latched for the + // composition. + if (!mFrameLatencyNeeded) return false; + + // Update mFrameEventHistory. + { + Mutex::Autolock lock(mFrameEventHistoryMutex); + mFrameEventHistory.addPostComposition(mCurrentFrameNumber, glDoneFence, presentFence, + compositorTiming); + } + + // Update mFrameTracker. + nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp(); + mFrameTracker.setDesiredPresentTime(desiredPresentTime); + + std::shared_ptr frameReadyFence = mSurfaceFlingerConsumer->getCurrentFenceTime(); + if (frameReadyFence->isValid()) { + mFrameTracker.setFrameReadyFence(std::move(frameReadyFence)); + } else { + // There was no fence for this frame, so assume that it was ready + // to be presented at the desired present time. + mFrameTracker.setFrameReadyTime(desiredPresentTime); + } + + if (presentFence->isValid()) { + mFrameTracker.setActualPresentFence(std::shared_ptr(presentFence)); + } else { + // The HWC doesn't support present fences, so use the refresh + // timestamp instead. + mFrameTracker.setActualPresentTime( + mFlinger->getHwComposer().getRefreshTimestamp(HWC_DISPLAY_PRIMARY)); + } + + mFrameTracker.advanceFrame(); + mFrameLatencyNeeded = false; + return true; +} + +std::vector BufferLayer::getOccupancyHistory(bool forceFlush) { + std::vector history; + status_t result = mSurfaceFlingerConsumer->getOccupancyHistory(forceFlush, &history); + if (result != NO_ERROR) { + ALOGW("[%s] Failed to obtain occupancy history (%d)", mName.string(), result); + return {}; + } + return history; +} + +bool BufferLayer::getTransformToDisplayInverse() const { + return mSurfaceFlingerConsumer->getTransformToDisplayInverse(); +} #ifdef USE_HWC2 void BufferLayer::releasePendingBuffer(nsecs_t dequeueReadyTime) { @@ -485,6 +600,10 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime return outDirtyRegion; } +void BufferLayer::setDefaultBufferSize(uint32_t w, uint32_t h) { + mSurfaceFlingerConsumer->setDefaultBufferSize(w, h); +} + #ifdef USE_HWC2 void BufferLayer::setPerFrameData(const sp& displayDevice) { // Apply this display's projection's viewport to the visible region @@ -529,28 +648,6 @@ void BufferLayer::setPerFrameData(const sp& displayDevice) return; } - // SolidColor layers - if (mActiveBuffer == nullptr) { - setCompositionType(hwcId, HWC2::Composition::SolidColor); - - // For now, we only support black for DimLayer - error = hwcLayer->setColor({0, 0, 0, 255}); - if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to set color: %s (%d)", mName.string(), to_string(error).c_str(), - static_cast(error)); - } - - // Clear out the transform, because it doesn't make sense absent a - // source buffer - error = hwcLayer->setTransform(HWC2::Transform::None); - if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to clear transform: %s (%d)", mName.string(), - to_string(error).c_str(), static_cast(error)); - } - - return; - } - // Device or Cursor layers if (mPotentialCursor) { ALOGV("[%s] Requesting Cursor composition", mName.string()); @@ -580,26 +677,24 @@ void BufferLayer::setPerFrameData(const sp& displayDevice) } #else -void BufferLayer::setPerFrameData(const sp& hw, +void BufferLayer::setAcquireFence(const sp& /* hw */, HWComposer::HWCLayerInterface& layer) { - // we have to set the visible region on every frame because - // we currently free it during onLayerDisplayed(), which is called - // after HWComposer::commit() -- every frame. - // Apply this display's projection's viewport to the visible region - // before giving it to the HWC HAL. - const Transform& tr = hw->getTransform(); - Region visible = tr.transform(visibleRegion.intersect(hw->getViewport())); - layer.setVisibleRegionScreen(visible); - layer.setSurfaceDamage(surfaceDamageRegion); - mIsGlesComposition = (layer.getCompositionType() == HWC_FRAMEBUFFER); - - if (mSidebandStream.get()) { - layer.setSidebandStream(mSidebandStream); - } else { - // NOTE: buffer can be NULL if the client never drew into this - // layer yet, or if we ran out of memory - layer.setBuffer(mActiveBuffer); + int fenceFd = -1; + + // TODO: there is a possible optimization here: we only need to set the + // acquire fence the first time a new buffer is acquired on EACH display. + + if (layer.getCompositionType() == HWC_OVERLAY || + layer.getCompositionType() == HWC_CURSOR_OVERLAY) { + sp fence = mSurfaceFlingerConsumer->getCurrentFence(); + if (fence->isValid()) { + fenceFd = fence->dup(); + if (fenceFd == -1) { + ALOGW("failed to dup layer fence, skipping sync: %d", errno); + } + } } + layer.setAcquireFenceFd(fenceFd); } #endif diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h index 882649ba70..418f032198 100644 --- a/services/surfaceflinger/BufferLayer.h +++ b/services/surfaceflinger/BufferLayer.h @@ -64,6 +64,12 @@ public: ~BufferLayer() override; + // If we have received a new buffer this frame, we will pass its surface + // damage down to hardware composer. Otherwise, we must send a region with + // one empty rect. + void useSurfaceDamage(); + void useEmptyDamage(); + // ----------------------------------------------------------------------- // Overriden from Layer // ----------------------------------------------------------------------- @@ -99,6 +105,23 @@ public: void onDraw(const RenderArea& renderArea, const Region& clip, bool useIdentityTransform) const override; +#ifdef USE_HWC2 + void onLayerDisplayed(const sp& releaseFence) override; +#else + void onLayerDisplayed(const sp& hw, + HWComposer::HWCLayerInterface* layer) override; +#endif + + void abandon() override; + bool shouldPresentNow(const DispSync& dispSync) const override; + void setTransformHint(uint32_t orientation) const override; + bool onPostComposition(const std::shared_ptr& glDoneFence, + const std::shared_ptr& presentFence, + const CompositorTiming& compositorTiming) override; + std::vector getOccupancyHistory(bool forceFlush) override; + bool getTransformToDisplayInverse() const override; + +public: bool onPreComposition(nsecs_t refreshStartTime) override; #ifdef USE_HWC2 @@ -114,13 +137,15 @@ public: */ Region latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime) override; bool isBufferLatched() const override { return mRefreshPending; } + void setDefaultBufferSize(uint32_t w, uint32_t h) override; #ifdef USE_HWC2 - void setPerFrameData(const sp& displayDevice); + void setPerFrameData(const sp& displayDevice) override; #else - void setPerFrameData(const sp& hw, - HWComposer::HWCLayerInterface& layer); + void setAcquireFence(const sp& hw, + HWComposer::HWCLayerInterface& layer) override; #endif + bool isOpaque(const Layer::State& s) const override; private: @@ -160,6 +185,8 @@ public: sp getProducer() const; private: + sp mSurfaceFlingerConsumer; + // Check all of the local sync points to ensure that all transactions // which need to have been applied prior to the frame which is about to // be latched have signaled diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp index 500f81f263..8a17f882d0 100644 --- a/services/surfaceflinger/ColorLayer.cpp +++ b/services/surfaceflinger/ColorLayer.cpp @@ -61,6 +61,36 @@ bool ColorLayer::isVisible() const { return !isHiddenByPolicy() && s.color.a; } +#ifdef USE_HWC2 +void ColorLayer::setPerFrameData(const sp& displayDevice) { + const Transform& tr = displayDevice->getTransform(); + const auto& viewport = displayDevice->getViewport(); + Region visible = tr.transform(visibleRegion.intersect(viewport)); + auto hwcId = displayDevice->getHwcDisplayId(); + auto& hwcInfo = mHwcLayers[hwcId]; + auto& hwcLayer = hwcInfo.layer; + auto error = hwcLayer->setVisibleRegion(visible); + + setCompositionType(hwcId, HWC2::Composition::SolidColor); + + half4 color = getColor(); + error = hwcLayer->setColor({static_cast(std::round(255.0f * color.r)), + static_cast(std::round(255.0f * color.g)), + static_cast(std::round(255.0f * color.b)), 255}); + if (error != HWC2::Error::None) { + ALOGE("[%s] Failed to set color: %s (%d)", mName.string(), to_string(error).c_str(), + static_cast(error)); + } + + // Clear out the transform, because it doesn't make sense absent a source buffer + error = hwcLayer->setTransform(HWC2::Transform::None); + if (error != HWC2::Error::None) { + ALOGE("[%s] Failed to clear transform: %s (%d)", mName.string(), to_string(error).c_str(), + static_cast(error)); + } +} +#endif + // --------------------------------------------------------------------------- }; // namespace android diff --git a/services/surfaceflinger/ColorLayer.h b/services/surfaceflinger/ColorLayer.h index 89013274af..debd3c3869 100644 --- a/services/surfaceflinger/ColorLayer.h +++ b/services/surfaceflinger/ColorLayer.h @@ -46,8 +46,29 @@ public: void releasePendingBuffer(nsecs_t) override {} #endif Region latchBuffer(bool&, nsecs_t) override { return Region(); } + void useSurfaceDamage() override {} + void useEmptyDamage() override {} bool isBufferLatched() const override { return false; } bool onPreComposition(nsecs_t) override { return true; } + void abandon() override {} +#ifdef USE_HWC2 + void setPerFrameData(const sp& displayDevice) override; +#else + void setAcquireFence(const sp& /*hw*/, + HWComposer::HWCLayerInterface& /*layer*/) override {} +#endif + void setDefaultBufferSize(uint32_t /*w*/, uint32_t /*h*/) override {} + bool shouldPresentNow(const DispSync& /*dispSync*/) const override { return false; } + bool onPostComposition(const std::shared_ptr& /*glDoneFence*/, + const std::shared_ptr& /*presentFence*/, + const CompositorTiming& /*compositorTiming*/) override { + return false; + } + void setTransformHint(uint32_t /*orientation*/) const override {} + std::vector getOccupancyHistory(bool /*forceFlush*/) override { + return {}; + } + bool getTransformToDisplayInverse() const override { return false; } }; // --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index a318a8f46a..c823d67d9f 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -69,7 +69,6 @@ Layer::Layer(SurfaceFlinger* flinger, const sp& client, const String8& n : contentDirty(false), sequence(uint32_t(android_atomic_inc(&sSequence))), mFlinger(flinger), - mSurfaceFlingerConsumer(NULL), mPremultipliedAlpha(true), mName(name), mTransactionFlags(0), @@ -153,23 +152,16 @@ Layer::~Layer() { // callbacks // --------------------------------------------------------------------------- +/* + * onLayerDisplayed is only meaningful for BufferLayer, but, is called through + * Layer. So, the implementation is done in BufferLayer. When called on a + * ColorLayer object, it's essentially a NOP. + */ #ifdef USE_HWC2 -void Layer::onLayerDisplayed(const sp& releaseFence) { - if (mHwcLayers.empty()) { - return; - } - if (mSurfaceFlingerConsumer) { - mSurfaceFlingerConsumer->setReleaseFence(releaseFence); - } -} +void Layer::onLayerDisplayed(const sp& /*releaseFence*/) {} #else void Layer::onLayerDisplayed(const sp& /* hw */, - HWComposer::HWCLayerInterface* layer) { - if (layer) { - layer->onDisplayed(); - mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence()); - } -} + HWComposer::HWCLayerInterface* /*layer*/) {} #endif void Layer::onRemovedFromCurrentState() { @@ -191,10 +183,8 @@ void Layer::onRemovedFromCurrentState() { void Layer::onRemoved() { // the layer is removed from SF mLayersPendingRemoval + abandon(); - if (mSurfaceFlingerConsumer) { - mSurfaceFlingerConsumer->abandon(); - } #ifdef USE_HWC2 destroyAllHwcLayers(); #endif @@ -690,105 +680,9 @@ void Layer::forceClientComposition(int32_t hwcId) { mHwcLayers[hwcId].forceClientComposition = true; } - -void Layer::setPerFrameData(const sp& displayDevice) { - // Apply this display's projection's viewport to the visible region - // before giving it to the HWC HAL. - const Transform& tr = displayDevice->getTransform(); - const auto& viewport = displayDevice->getViewport(); - Region visible = tr.transform(visibleRegion.intersect(viewport)); - auto hwcId = displayDevice->getHwcDisplayId(); - auto& hwcInfo = mHwcLayers[hwcId]; - auto& hwcLayer = hwcInfo.layer; - auto error = hwcLayer->setVisibleRegion(visible); - if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(), - to_string(error).c_str(), static_cast(error)); - visible.dump(LOG_TAG); - } - - error = hwcLayer->setSurfaceDamage(surfaceDamageRegion); - if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to set surface damage: %s (%d)", mName.string(), - to_string(error).c_str(), static_cast(error)); - surfaceDamageRegion.dump(LOG_TAG); - } - - // Sideband layers - if (mSidebandStream.get()) { - setCompositionType(hwcId, HWC2::Composition::Sideband); - ALOGV("[%s] Requesting Sideband composition", mName.string()); - error = hwcLayer->setSidebandStream(mSidebandStream->handle()); - if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to set sideband stream %p: %s (%d)", mName.string(), - mSidebandStream->handle(), to_string(error).c_str(), static_cast(error)); - } - return; - } - - // Client layers - if (hwcInfo.forceClientComposition || - (mActiveBuffer != nullptr && mActiveBuffer->handle == nullptr)) { - ALOGV("[%s] Requesting Client composition", mName.string()); - setCompositionType(hwcId, HWC2::Composition::Client); - return; - } - - // SolidColor layers - if (mActiveBuffer == nullptr) { - setCompositionType(hwcId, HWC2::Composition::SolidColor); - - half4 color = getColor(); - error = hwcLayer->setColor({static_cast(std::round(255.0f * color.r)), - static_cast(std::round(255.0f * color.g)), - static_cast(std::round(255.0f * color.b)), 255}); - if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to set color: %s (%d)", mName.string(), to_string(error).c_str(), - static_cast(error)); - } - - // Clear out the transform, because it doesn't make sense absent a - // source buffer - error = hwcLayer->setTransform(HWC2::Transform::None); - if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to clear transform: %s (%d)", mName.string(), - to_string(error).c_str(), static_cast(error)); - } - - return; - } - - // Device or Cursor layers - if (mPotentialCursor) { - ALOGV("[%s] Requesting Cursor composition", mName.string()); - setCompositionType(hwcId, HWC2::Composition::Cursor); - } else { - ALOGV("[%s] Requesting Device composition", mName.string()); - setCompositionType(hwcId, HWC2::Composition::Device); - } - - ALOGV("setPerFrameData: dataspace = %d", mCurrentState.dataSpace); - error = hwcLayer->setDataspace(mCurrentState.dataSpace); - if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), mCurrentState.dataSpace, - to_string(error).c_str(), static_cast(error)); - } - - uint32_t hwcSlot = 0; - sp hwcBuffer; - hwcInfo.bufferCache.getHwcBuffer(mActiveBufferSlot, mActiveBuffer, &hwcSlot, &hwcBuffer); - - auto acquireFence = mSurfaceFlingerConsumer->getCurrentFence(); - error = hwcLayer->setBuffer(hwcSlot, hwcBuffer, acquireFence); - if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(), mActiveBuffer->handle, - to_string(error).c_str(), static_cast(error)); - } -} - #else void Layer::setPerFrameData(const sp& hw, - HWComposer::HWCLayerInterface& layer) { + HWComposer::HWCLayerInterface& layer) { // we have to set the visible region on every frame because // we currently free it during onLayerDisplayed(), which is called // after HWComposer::commit() -- every frame. @@ -810,6 +704,7 @@ void Layer::setPerFrameData(const sp& hw, } #endif + #ifdef USE_HWC2 void Layer::updateCursorPosition(const sp& displayDevice) { auto hwcId = displayDevice->getHwcDisplayId(); @@ -844,26 +739,6 @@ void Layer::updateCursorPosition(const sp& displayDevice) { static_cast(error)); } #else -void Layer::setAcquireFence(const sp& /* hw */, - HWComposer::HWCLayerInterface& layer) { - int fenceFd = -1; - - // TODO: there is a possible optimization here: we only need to set the - // acquire fence the first time a new buffer is acquired on EACH display. - - if (layer.getCompositionType() == HWC_OVERLAY || - layer.getCompositionType() == HWC_CURSOR_OVERLAY) { - sp fence = mSurfaceFlingerConsumer->getCurrentFence(); - if (fence->isValid()) { - fenceFd = fence->dup(); - if (fenceFd == -1) { - ALOGW("failed to dup layer fence, skipping sync: %d", errno); - } - } - } - layer.setAcquireFenceFd(fenceFd); -} - Rect Layer::getPosition(const sp& hw) { // this gives us only the "orientation" component of the transform const State& s(getCurrentState()); @@ -1176,7 +1051,7 @@ uint32_t Layer::doTransaction(uint32_t flags) { const bool sizeChanged = (c.requested.w != s.requested.w) || (c.requested.h != s.requested.h); - if (mSurfaceFlingerConsumer && sizeChanged) { + if (sizeChanged) { // the size changed, we need to ask our client to request a new buffer ALOGD_IF(DEBUG_RESIZE, "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n" @@ -1192,7 +1067,7 @@ uint32_t Layer::doTransaction(uint32_t flags) { // record the new size, form this point on, when the client request // a buffer, it'll get the new size. - mSurfaceFlingerConsumer->setDefaultBufferSize(c.requested.w, c.requested.h); + setDefaultBufferSize(c.requested.w, c.requested.h); } // Don't let Layer::doTransaction update the drawing state @@ -1527,86 +1402,11 @@ void Layer::deferTransactionUntil(const sp& barrierHandle, uint64_t fra deferTransactionUntil(handle->owner.promote(), frameNumber); } -void Layer::useSurfaceDamage() { - if (mFlinger->mForceFullDamage) { - surfaceDamageRegion = Region::INVALID_REGION; - } else { - surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage(); - } -} - -void Layer::useEmptyDamage() { - surfaceDamageRegion.clear(); -} // ---------------------------------------------------------------------------- // pageflip handling... // ---------------------------------------------------------------------------- -bool Layer::shouldPresentNow(const DispSync& dispSync) const { - if (mSidebandStreamChanged || mAutoRefresh) { - return true; - } - - Mutex::Autolock lock(mQueueItemLock); - if (mQueueItems.empty()) { - return false; - } - auto timestamp = mQueueItems[0].mTimestamp; - nsecs_t expectedPresent = mSurfaceFlingerConsumer->computeExpectedPresent(dispSync); - - // Ignore timestamps more than a second in the future - bool isPlausible = timestamp < (expectedPresent + s2ns(1)); - ALOGW_IF(!isPlausible, - "[%s] Timestamp %" PRId64 " seems implausible " - "relative to expectedPresent %" PRId64, - mName.string(), timestamp, expectedPresent); - - bool isDue = timestamp < expectedPresent; - return isDue || !isPlausible; -} - -bool Layer::onPostComposition(const std::shared_ptr& glDoneFence, - const std::shared_ptr& presentFence, - const CompositorTiming& compositorTiming) { - // mFrameLatencyNeeded is true when a new frame was latched for the - // composition. - if (!mFrameLatencyNeeded) return false; - - // Update mFrameEventHistory. - { - Mutex::Autolock lock(mFrameEventHistoryMutex); - mFrameEventHistory.addPostComposition(mCurrentFrameNumber, glDoneFence, presentFence, - compositorTiming); - } - - // Update mFrameTracker. - nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp(); - mFrameTracker.setDesiredPresentTime(desiredPresentTime); - - std::shared_ptr frameReadyFence = mSurfaceFlingerConsumer->getCurrentFenceTime(); - if (frameReadyFence->isValid()) { - mFrameTracker.setFrameReadyFence(std::move(frameReadyFence)); - } else { - // There was no fence for this frame, so assume that it was ready - // to be presented at the desired present time. - mFrameTracker.setFrameReadyTime(desiredPresentTime); - } - - if (presentFence->isValid()) { - mFrameTracker.setActualPresentFence(std::shared_ptr(presentFence)); - } else { - // The HWC doesn't support present fences, so use the refresh - // timestamp instead. - mFrameTracker.setActualPresentTime( - mFlinger->getHwComposer().getRefreshTimestamp(HWC_DISPLAY_PRIMARY)); - } - - mFrameTracker.advanceFrame(); - mFrameLatencyNeeded = false; - return true; -} - bool Layer::isHiddenByPolicy() const { const Layer::State& s(mDrawingState); const auto& parent = mDrawingParent.promote(); @@ -1641,9 +1441,7 @@ void Layer::updateTransformHint(const sp& hw) const { orientation = 0; } } - if (mSurfaceFlingerConsumer) { - mSurfaceFlingerConsumer->setTransformHint(orientation); - } + setTransformHint(orientation); } // ---------------------------------------------------------------------------- @@ -1788,26 +1586,6 @@ void Layer::addAndGetFrameTimestamps(const NewFrameEventsEntry* newTimestamps, } } -std::vector Layer::getOccupancyHistory(bool forceFlush) { - std::vector history; - - if (!mSurfaceFlingerConsumer) return {}; - - status_t result = mSurfaceFlingerConsumer->getOccupancyHistory(forceFlush, &history); - if (result != NO_ERROR) { - ALOGW("[%s] Failed to obtain occupancy history (%d)", mName.string(), result); - return {}; - } - return history; -} - -bool Layer::getTransformToDisplayInverse() const { - if (mSurfaceFlingerConsumer) { - return mSurfaceFlingerConsumer->getTransformToDisplayInverse(); - } - return false; -} - size_t Layer::getChildrenCount() const { size_t count = 0; for (const sp& child : mCurrentChildren) { diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index db94a31c5e..004d22057b 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -42,7 +42,6 @@ #include "LayerVector.h" #include "MonitoredProducer.h" #include "SurfaceFlinger.h" -#include "SurfaceFlingerConsumer.h" #include "Transform.h" #include @@ -230,8 +229,8 @@ public: // If we have received a new buffer this frame, we will pass its surface // damage down to hardware composer. Otherwise, we must send a region with // one empty rect. - void useSurfaceDamage(); - void useEmptyDamage(); + virtual void useSurfaceDamage() = 0; + virtual void useEmptyDamage() = 0; uint32_t getTransactionFlags(uint32_t flags); uint32_t setTransactionFlags(uint32_t flags); @@ -294,10 +293,12 @@ protected: bool useIdentityTransform) const = 0; public: + virtual void setDefaultBufferSize(uint32_t w, uint32_t h) = 0; + #ifdef USE_HWC2 void setGeometry(const sp& displayDevice, uint32_t z); void forceClientComposition(int32_t hwcId); - void setPerFrameData(const sp& displayDevice); + virtual void setPerFrameData(const sp& displayDevice) = 0; // callIntoHwc exists so we can update our local state and call // acceptDisplayChanges without unnecessarily updating the device's state @@ -309,8 +310,8 @@ public: #else void setGeometry(const sp& hw, HWComposer::HWCLayerInterface& layer); void setPerFrameData(const sp& hw, HWComposer::HWCLayerInterface& layer); - void setAcquireFence(const sp& hw, - HWComposer::HWCLayerInterface& layer); + virtual void setAcquireFence(const sp& hw, + HWComposer::HWCLayerInterface& layer) = 0; Rect getPosition(const sp& hw); #endif @@ -318,12 +319,16 @@ public: * called after page-flip */ #ifdef USE_HWC2 - void onLayerDisplayed(const sp& releaseFence); + virtual void onLayerDisplayed(const sp& releaseFence); #else - void onLayerDisplayed(const sp& hw, HWComposer::HWCLayerInterface* layer); + virtual void onLayerDisplayed(const sp& hw, + HWComposer::HWCLayerInterface* layer); #endif - bool shouldPresentNow(const DispSync& dispSync) const; + virtual void abandon() = 0; + + virtual bool shouldPresentNow(const DispSync& dispSync) const = 0; + virtual void setTransformHint(uint32_t orientation) const = 0; /* * called before composition. @@ -335,9 +340,9 @@ public: * called after composition. * returns true if the layer latched a new buffer this frame. */ - bool onPostComposition(const std::shared_ptr& glDoneFence, - const std::shared_ptr& presentFence, - const CompositorTiming& compositorTiming); + virtual bool onPostComposition(const std::shared_ptr& glDoneFence, + const std::shared_ptr& presentFence, + const CompositorTiming& compositorTiming) = 0; #ifdef USE_HWC2 // If a buffer was replaced this frame, release the former buffer @@ -461,13 +466,13 @@ public: void logFrameStats(); void getFrameStats(FrameStats* outStats) const; - std::vector getOccupancyHistory(bool forceFlush); + virtual std::vector getOccupancyHistory(bool forceFlush) = 0; void onDisconnect(); void addAndGetFrameTimestamps(const NewFrameEventsEntry* newEntry, FrameEventHistoryDelta* outDelta); - bool getTransformToDisplayInverse() const; + virtual bool getTransformToDisplayInverse() const = 0; Transform getTransform() const; @@ -524,6 +529,7 @@ protected: virtual void onFirstRef(); friend class SurfaceInterceptor; + void commitTransaction(const State& stateToCommit); uint32_t getEffectiveUsage(uint32_t usage) const; @@ -545,7 +551,6 @@ protected: void addZOrderRelative(const wp& relative); void removeZOrderRelative(const wp& relative); -protected: class SyncPoint { public: explicit SyncPoint(uint64_t frameNumber) @@ -617,8 +622,6 @@ public: protected: // ----------------------------------------------------------------------- - // constants - sp mSurfaceFlingerConsumer; bool mPremultipliedAlpha; String8 mName; String8 mTransactionName; // A cached version of "TX - " + mName for systraces -- cgit v1.2.3-59-g8ed1b From eb13f9e6a31020ad15f4c5fffba47d492fa957f7 Mon Sep 17 00:00:00 2001 From: Ivan Lozano Date: Thu, 9 Nov 2017 12:39:31 -0800 Subject: Fix sanitizer in SurfaceFlinger BufferLayer. The value -1U causes an runtime error on integer sanitized builds. This changes the value to UINT32_MAX. Bug: 30969751 Test: Compiles and device boots without runtime error. Change-Id: I0597386d9b485f0a0343e36b8afd3989bc77aadb --- services/surfaceflinger/BufferLayer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'services/surfaceflinger/BufferLayer.cpp') diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index 45093be1a3..fc0949dd90 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -54,7 +54,7 @@ BufferLayer::BufferLayer(SurfaceFlinger* flinger, const sp& client, cons uint32_t w, uint32_t h, uint32_t flags) : Layer(flinger, client, name, w, h, flags), mSurfaceFlingerConsumer(nullptr), - mTextureName(-1U), + mTextureName(UINT32_MAX), mFormat(PIXEL_FORMAT_NONE), mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), mBufferLatched(false), -- cgit v1.2.3-59-g8ed1b From 83ce7c162855742a2d9eeebc0cd70fe48d2cd125 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Thu, 19 Oct 2017 15:18:55 -0700 Subject: surfaceflinger: remove USE_HWC2 Remove USE_HWC2 and assume it to be true. Remove all !USE_HWC2 code. This also fixes a compile error in tests/fakehwc, which never defines USE_HWC2. Test: boots taimen and hikey960 Change-Id: Ie6d2fcf884aa6fc715ab0ce19a1e0f7c8acf734c --- services/surfaceflinger/Android.mk | 3 - services/surfaceflinger/BufferLayer.cpp | 55 ---------- services/surfaceflinger/BufferLayer.h | 12 --- services/surfaceflinger/ColorLayer.cpp | 2 - services/surfaceflinger/ColorLayer.h | 7 -- services/surfaceflinger/DisplayDevice.cpp | 79 -------------- services/surfaceflinger/DisplayDevice.h | 33 ------ .../DisplayHardware/DisplaySurface.h | 8 -- .../DisplayHardware/FramebufferSurface.cpp | 79 -------------- .../DisplayHardware/FramebufferSurface.h | 12 --- .../surfaceflinger/DisplayHardware/HWComposer.h | 6 -- .../DisplayHardware/VirtualDisplaySurface.cpp | 29 ------ .../DisplayHardware/VirtualDisplaySurface.h | 6 -- services/surfaceflinger/EventControlThread.cpp | 5 - services/surfaceflinger/Layer.cpp | 114 +-------------------- services/surfaceflinger/Layer.h | 23 ----- services/surfaceflinger/RenderArea.h | 4 +- .../RenderEngine/GLES20RenderEngine.cpp | 14 --- .../RenderEngine/GLES20RenderEngine.h | 2 - .../surfaceflinger/RenderEngine/RenderEngine.h | 2 - services/surfaceflinger/SurfaceFlinger.cpp | 2 - services/surfaceflinger/SurfaceFlinger.h | 50 --------- services/surfaceflinger/SurfaceFlingerConsumer.cpp | 6 -- services/surfaceflinger/SurfaceFlingerConsumer.h | 4 - .../tests/fakehwc/FakeComposerClient.h | 4 + 25 files changed, 6 insertions(+), 555 deletions(-) (limited to 'services/surfaceflinger/BufferLayer.cpp') diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk index 469e5989ba..2a78aa597f 100644 --- a/services/surfaceflinger/Android.mk +++ b/services/surfaceflinger/Android.mk @@ -54,7 +54,6 @@ LOCAL_C_INCLUDES := \ LOCAL_CFLAGS := -DLOG_TAG=\"SurfaceFlinger\" LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES -LOCAL_CFLAGS += -DUSE_HWC2 LOCAL_CFLAGS += -fvisibility=hidden -Werror=format @@ -120,8 +119,6 @@ LOCAL_CFLAGS := -DLOG_TAG=\"SurfaceFlinger\" LOCAL_INIT_RC := surfaceflinger.rc -LOCAL_CFLAGS += -DUSE_HWC2 - LOCAL_SRC_FILES := \ main_surfaceflinger.cpp diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index fc0949dd90..0c1693b53b 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -61,9 +61,7 @@ BufferLayer::BufferLayer(SurfaceFlinger* flinger, const sp& client, cons mPreviousFrameNumber(0), mUpdateTexImageFailed(false), mRefreshPending(false) { -#ifdef USE_HWC2 ALOGV("Creating Layer %s", name.string()); -#endif mFlinger->getRenderEngine().genTextures(1, &mTextureName); mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName); @@ -90,14 +88,12 @@ BufferLayer::~BufferLayer() { } mFlinger->deleteTextureAsync(mTextureName); -#ifdef USE_HWC2 if (!mHwcLayers.empty()) { ALOGE("Found stale hardware composer layers when destroying " "surface flinger layer %s", mName.string()); destroyAllHwcLayers(); } -#endif } void BufferLayer::useSurfaceDamage() { @@ -265,22 +261,12 @@ void BufferLayer::onDraw(const RenderArea& renderArea, const Region& clip, engine.disableTexturing(); } -#ifdef USE_HWC2 void BufferLayer::onLayerDisplayed(const sp& releaseFence) { if (mHwcLayers.empty()) { return; } mSurfaceFlingerConsumer->setReleaseFence(releaseFence); } -#else -void BufferLayer::onLayerDisplayed(const sp& /*hw*/, - HWComposer::HWCLayerInterface* layer) { - if (layer) { - layer->onDisplayed(); - mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence()); - } -} -#endif void BufferLayer::abandon() { mSurfaceFlingerConsumer->abandon(); @@ -376,7 +362,6 @@ bool BufferLayer::getTransformToDisplayInverse() const { return mSurfaceFlingerConsumer->getTransformToDisplayInverse(); } -#ifdef USE_HWC2 void BufferLayer::releasePendingBuffer(nsecs_t dequeueReadyTime) { if (!mSurfaceFlingerConsumer->releasePendingBuffer()) { return; @@ -393,7 +378,6 @@ void BufferLayer::releasePendingBuffer(nsecs_t dequeueReadyTime) { std::move(releaseFenceTime)); } } -#endif Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime) { ATRACE_CALL(); @@ -523,16 +507,6 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime { Mutex::Autolock lock(mFrameEventHistoryMutex); mFrameEventHistory.addLatch(mCurrentFrameNumber, latchTime); -#ifndef USE_HWC2 - auto releaseFenceTime = - std::make_shared(mSurfaceFlingerConsumer->getPrevFinalReleaseFence()); - mReleaseTimeline.updateSignalTimes(); - mReleaseTimeline.push(releaseFenceTime); - if (mPreviousFrameNumber != 0) { - mFrameEventHistory.addRelease(mPreviousFrameNumber, latchTime, - std::move(releaseFenceTime)); - } -#endif } mRefreshPending = true; @@ -604,7 +578,6 @@ void BufferLayer::setDefaultBufferSize(uint32_t w, uint32_t h) { mSurfaceFlingerConsumer->setDefaultBufferSize(w, h); } -#ifdef USE_HWC2 void BufferLayer::setPerFrameData(const sp& displayDevice) { // Apply this display's projection's viewport to the visible region // before giving it to the HWC HAL. @@ -676,28 +649,6 @@ void BufferLayer::setPerFrameData(const sp& displayDevice) } } -#else -void BufferLayer::setAcquireFence(const sp& /* hw */, - HWComposer::HWCLayerInterface& layer) { - int fenceFd = -1; - - // TODO: there is a possible optimization here: we only need to set the - // acquire fence the first time a new buffer is acquired on EACH display. - - if (layer.getCompositionType() == HWC_OVERLAY || - layer.getCompositionType() == HWC_CURSOR_OVERLAY) { - sp fence = mSurfaceFlingerConsumer->getCurrentFence(); - if (fence->isValid()) { - fenceFd = fence->dup(); - if (fenceFd == -1) { - ALOGW("failed to dup layer fence, skipping sync: %d", errno); - } - } - } - layer.setAcquireFenceFd(fenceFd); -} -#endif - bool BufferLayer::isOpaque(const Layer::State& s) const { // if we don't have a buffer or sidebandStream yet, we're translucent regardless of the // layer's opaque flag. @@ -871,9 +822,7 @@ void BufferLayer::drawWithOpenGL(const RenderArea& renderArea, bool useIdentityT RenderEngine& engine(mFlinger->getRenderEngine()); engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), false /* disableTexture */, getColor()); -#ifdef USE_HWC2 engine.setSourceDataSpace(mCurrentState.dataSpace); -#endif engine.drawMesh(mMesh); engine.disableBlending(); } @@ -913,7 +862,6 @@ uint64_t BufferLayer::getHeadFrameNumber() const { } bool BufferLayer::headFenceHasSignaled() const { -#ifdef USE_HWC2 if (latchUnsignaledBuffers()) { return true; } @@ -930,9 +878,6 @@ bool BufferLayer::headFenceHasSignaled() const { return true; } return mQueueItems[0].mFenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING; -#else - return true; -#endif } uint32_t BufferLayer::getEffectiveScalingMode() const { diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h index 418f032198..078302bc75 100644 --- a/services/surfaceflinger/BufferLayer.h +++ b/services/surfaceflinger/BufferLayer.h @@ -105,12 +105,7 @@ public: void onDraw(const RenderArea& renderArea, const Region& clip, bool useIdentityTransform) const override; -#ifdef USE_HWC2 void onLayerDisplayed(const sp& releaseFence) override; -#else - void onLayerDisplayed(const sp& hw, - HWComposer::HWCLayerInterface* layer) override; -#endif void abandon() override; bool shouldPresentNow(const DispSync& dispSync) const override; @@ -124,10 +119,8 @@ public: public: bool onPreComposition(nsecs_t refreshStartTime) override; -#ifdef USE_HWC2 // If a buffer was replaced this frame, release the former buffer void releasePendingBuffer(nsecs_t dequeueReadyTime); -#endif /* * latchBuffer - called each time the screen is redrawn and returns whether @@ -139,12 +132,7 @@ public: bool isBufferLatched() const override { return mRefreshPending; } void setDefaultBufferSize(uint32_t w, uint32_t h) override; -#ifdef USE_HWC2 void setPerFrameData(const sp& displayDevice) override; -#else - void setAcquireFence(const sp& hw, - HWComposer::HWCLayerInterface& layer) override; -#endif bool isOpaque(const Layer::State& s) const override; diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp index 8a17f882d0..292e1a7350 100644 --- a/services/surfaceflinger/ColorLayer.cpp +++ b/services/surfaceflinger/ColorLayer.cpp @@ -61,7 +61,6 @@ bool ColorLayer::isVisible() const { return !isHiddenByPolicy() && s.color.a; } -#ifdef USE_HWC2 void ColorLayer::setPerFrameData(const sp& displayDevice) { const Transform& tr = displayDevice->getTransform(); const auto& viewport = displayDevice->getViewport(); @@ -89,7 +88,6 @@ void ColorLayer::setPerFrameData(const sp& displayDevice) { static_cast(error)); } } -#endif // --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/ColorLayer.h b/services/surfaceflinger/ColorLayer.h index debd3c3869..4022b319fa 100644 --- a/services/surfaceflinger/ColorLayer.h +++ b/services/surfaceflinger/ColorLayer.h @@ -42,21 +42,14 @@ public: void notifyAvailableFrames() override {} PixelFormat getPixelFormat() const override { return PIXEL_FORMAT_NONE; } uint32_t getEffectiveScalingMode() const override { return 0; } -#ifdef USE_HWC2 void releasePendingBuffer(nsecs_t) override {} -#endif Region latchBuffer(bool&, nsecs_t) override { return Region(); } void useSurfaceDamage() override {} void useEmptyDamage() override {} bool isBufferLatched() const override { return false; } bool onPreComposition(nsecs_t) override { return true; } void abandon() override {} -#ifdef USE_HWC2 void setPerFrameData(const sp& displayDevice) override; -#else - void setAcquireFence(const sp& /*hw*/, - HWComposer::HWCLayerInterface& /*layer*/) override {} -#endif void setDefaultBufferSize(uint32_t /*w*/, uint32_t /*h*/) override {} bool shouldPresentNow(const DispSync& /*dispSync*/) const override { return false; } bool onPostComposition(const std::shared_ptr& /*glDoneFence*/, diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp index 0244c1b862..ef7d482f28 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -38,9 +38,7 @@ #include "DisplayHardware/DisplaySurface.h" #include "DisplayHardware/HWComposer.h" -#ifdef USE_HWC2 #include "DisplayHardware/HWC2.h" -#endif #include "RenderEngine/RenderEngine.h" #include "clz.h" @@ -86,9 +84,6 @@ DisplayDevice::DisplayDevice( const sp& flinger, DisplayType type, int32_t hwcId, -#ifndef USE_HWC2 - int format, -#endif bool isSecure, const wp& displayToken, const sp& displaySurface, @@ -105,9 +100,6 @@ DisplayDevice::DisplayDevice( mSurface(EGL_NO_SURFACE), mDisplayWidth(), mDisplayHeight(), -#ifndef USE_HWC2 - mFormat(), -#endif mFlags(), mPageFlipCount(), mIsSecure(isSecure), @@ -121,12 +113,8 @@ DisplayDevice::DisplayDevice( mNativeWindow = surface = new Surface(producer, false); ANativeWindow* const window = mNativeWindow.get(); -#ifdef USE_HWC2 mActiveColorMode = HAL_COLOR_MODE_NATIVE; mDisplayHasWideColor = supportWideColor; -#else - (void) supportWideColor; -#endif /* * Create our display's surface */ @@ -134,13 +122,8 @@ DisplayDevice::DisplayDevice( EGLSurface eglSurface; EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (config == EGL_NO_CONFIG) { -#ifdef USE_HWC2 config = RenderEngine::chooseEglConfig(display, PIXEL_FORMAT_RGBA_8888, /*logConfig*/ false); -#else - config = RenderEngine::chooseEglConfig(display, format, - /*logConfig*/ false); -#endif } eglSurface = eglCreateWindowSurface(display, config, window, NULL); eglQuerySurface(display, eglSurface, EGL_WIDTH, &mDisplayWidth); @@ -159,9 +142,6 @@ DisplayDevice::DisplayDevice( mConfig = config; mDisplay = display; mSurface = eglSurface; -#ifndef USE_HWC2 - mFormat = format; -#endif mPageFlipCount = 0; mViewport.makeInvalid(); mFrame.makeInvalid(); @@ -202,10 +182,6 @@ DisplayDevice::~DisplayDevice() { void DisplayDevice::disconnect(HWComposer& hwc) { if (mHwcDisplayId >= 0) { hwc.disconnectDisplay(mHwcDisplayId); -#ifndef USE_HWC2 - if (mHwcDisplayId >= DISPLAY_VIRTUAL) - hwc.freeDisplayId(mHwcDisplayId); -#endif mHwcDisplayId = -1; } } @@ -222,12 +198,6 @@ int DisplayDevice::getHeight() const { return mDisplayHeight; } -#ifndef USE_HWC2 -PixelFormat DisplayDevice::getFormat() const { - return mFormat; -} -#endif - EGLSurface DisplayDevice::getEGLSurface() const { return mSurface; } @@ -243,12 +213,6 @@ uint32_t DisplayDevice::getPageFlipCount() const { return mPageFlipCount; } -#ifndef USE_HWC2 -status_t DisplayDevice::compositionComplete() const { - return mDisplaySurface->compositionComplete(); -} -#endif - void DisplayDevice::flip(const Region& dirty) const { mFlinger->getRenderEngine().checkErrors(); @@ -269,7 +233,6 @@ status_t DisplayDevice::beginFrame(bool mustRecompose) const { return mDisplaySurface->beginFrame(mustRecompose); } -#ifdef USE_HWC2 status_t DisplayDevice::prepareFrame(HWComposer& hwc) { status_t error = hwc.prepare(*this); if (error != NO_ERROR) { @@ -293,41 +256,9 @@ status_t DisplayDevice::prepareFrame(HWComposer& hwc) { } return mDisplaySurface->prepareFrame(compositionType); } -#else -status_t DisplayDevice::prepareFrame(const HWComposer& hwc) const { - DisplaySurface::CompositionType compositionType; - bool haveGles = hwc.hasGlesComposition(mHwcDisplayId); - bool haveHwc = hwc.hasHwcComposition(mHwcDisplayId); - if (haveGles && haveHwc) { - compositionType = DisplaySurface::COMPOSITION_MIXED; - } else if (haveGles) { - compositionType = DisplaySurface::COMPOSITION_GLES; - } else if (haveHwc) { - compositionType = DisplaySurface::COMPOSITION_HWC; - } else { - // Nothing to do -- when turning the screen off we get a frame like - // this. Call it a HWC frame since we won't be doing any GLES work but - // will do a prepare/set cycle. - compositionType = DisplaySurface::COMPOSITION_HWC; - } - return mDisplaySurface->prepareFrame(compositionType); -} -#endif void DisplayDevice::swapBuffers(HWComposer& hwc) const { -#ifdef USE_HWC2 if (hwc.hasClientComposition(mHwcDisplayId)) { -#else - // We need to call eglSwapBuffers() if: - // (1) we don't have a hardware composer, or - // (2) we did GLES composition this frame, and either - // (a) we have framebuffer target support (not present on legacy - // devices, where HWComposer::commit() handles things); or - // (b) this is a virtual display - if (hwc.initCheck() != NO_ERROR || - (hwc.hasGlesComposition(mHwcDisplayId) && - (hwc.supportsFramebufferTarget() || mType >= DISPLAY_VIRTUAL))) { -#endif EGLBoolean success = eglSwapBuffers(mDisplay, mSurface); if (!success) { EGLint error = eglGetError(); @@ -349,17 +280,9 @@ void DisplayDevice::swapBuffers(HWComposer& hwc) const { } } -#ifdef USE_HWC2 void DisplayDevice::onSwapBuffersCompleted() const { mDisplaySurface->onFrameCommitted(); } -#else -void DisplayDevice::onSwapBuffersCompleted(HWComposer& hwc) const { - if (hwc.initCheck() == NO_ERROR) { - mDisplaySurface->onFrameCommitted(); - } -} -#endif uint32_t DisplayDevice::getFlags() const { @@ -437,7 +360,6 @@ int DisplayDevice::getActiveConfig() const { } // ---------------------------------------------------------------------------- -#ifdef USE_HWC2 void DisplayDevice::setActiveColorMode(android_color_mode_t mode) { mActiveColorMode = mode; } @@ -450,7 +372,6 @@ void DisplayDevice::setCompositionDataSpace(android_dataspace dataspace) { ANativeWindow* const window = mNativeWindow.get(); native_window_set_buffers_data_space(window, dataspace); } -#endif // ---------------------------------------------------------------------------- diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h index 49fef5805f..50e30b2571 100644 --- a/services/surfaceflinger/DisplayDevice.h +++ b/services/surfaceflinger/DisplayDevice.h @@ -21,18 +21,13 @@ #include -#ifndef USE_HWC2 -#include -#endif #include #include #include -#ifdef USE_HWC2 #include #include -#endif #include #include #include @@ -41,9 +36,7 @@ #include #include "RenderArea.h" -#ifdef USE_HWC2 #include -#endif struct ANativeWindow; @@ -90,9 +83,6 @@ public: const sp& flinger, DisplayType type, int32_t hwcId, -#ifndef USE_HWC2 - int format, -#endif bool isSecure, const wp& displayToken, const sp& displaySurface, @@ -117,9 +107,6 @@ public: int getWidth() const; int getHeight() const; -#ifndef USE_HWC2 - PixelFormat getFormat() const; -#endif uint32_t getFlags() const; EGLSurface getEGLSurface() const; @@ -150,24 +137,13 @@ public: // We pass in mustRecompose so we can keep VirtualDisplaySurface's state // machine happy without actually queueing a buffer if nothing has changed status_t beginFrame(bool mustRecompose) const; -#ifdef USE_HWC2 status_t prepareFrame(HWComposer& hwc); bool getWideColorSupport() const { return mDisplayHasWideColor; } -#else - status_t prepareFrame(const HWComposer& hwc) const; -#endif void swapBuffers(HWComposer& hwc) const; -#ifndef USE_HWC2 - status_t compositionComplete() const; -#endif // called after h/w composer has completed its set() call -#ifdef USE_HWC2 void onSwapBuffersCompleted() const; -#else - void onSwapBuffersCompleted(HWComposer& hwc) const; -#endif Rect getBounds() const { return Rect(mDisplayWidth, mDisplayHeight); @@ -189,11 +165,9 @@ public: void setPowerMode(int mode); bool isDisplayOn() const; -#ifdef USE_HWC2 android_color_mode_t getActiveColorMode() const; void setActiveColorMode(android_color_mode_t mode); void setCompositionDataSpace(android_dataspace dataspace); -#endif /* ------------------------------------------------------------------------ * Display active config management. @@ -228,9 +202,6 @@ private: EGLSurface mSurface; int mDisplayWidth; int mDisplayHeight; -#ifndef USE_HWC2 - PixelFormat mFormat; -#endif uint32_t mFlags; mutable uint32_t mPageFlipCount; String8 mDisplayName; @@ -269,7 +240,6 @@ private: int mPowerMode; // Current active config int mActiveConfig; -#ifdef USE_HWC2 // current active color mode android_color_mode_t mActiveColorMode; @@ -277,7 +247,6 @@ private: // Initialized by SurfaceFlinger when the DisplayDevice is created. // Fed to RenderEngine during composition. bool mDisplayHasWideColor; -#endif }; struct DisplayDeviceState { @@ -319,12 +288,10 @@ public: bool isSecure() const override { return mDevice->isSecure(); } bool needsFiltering() const override { return mDevice->needsFiltering(); } Rect getSourceCrop() const override { return mSourceCrop; } -#ifdef USE_HWC2 bool getWideColorSupport() const override { return mDevice->getWideColorSupport(); } android_color_mode_t getActiveColorMode() const override { return mDevice->getActiveColorMode(); } -#endif private: const sp mDevice; diff --git a/services/surfaceflinger/DisplayHardware/DisplaySurface.h b/services/surfaceflinger/DisplayHardware/DisplaySurface.h index cb08f084fe..f744f5cf21 100644 --- a/services/surfaceflinger/DisplayHardware/DisplaySurface.h +++ b/services/surfaceflinger/DisplayHardware/DisplaySurface.h @@ -50,14 +50,6 @@ public: }; virtual status_t prepareFrame(CompositionType compositionType) = 0; -#ifndef USE_HWC2 - // Should be called when composition rendering is complete for a frame (but - // eglSwapBuffers hasn't necessarily been called). Required by certain - // older drivers for synchronization. - // TODO: Remove this when we drop support for HWC 1.0. - virtual status_t compositionComplete() = 0; -#endif - // Inform the surface that GLES composition is complete for this frame, and // the surface should make sure that HWComposer has the correct buffer for // this frame. Some implementations may only push a new buffer to diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp index 93c6d5486f..182629c97e 100644 --- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp +++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp @@ -59,32 +59,21 @@ FramebufferSurface::FramebufferSurface(HWComposer& hwc, int disp, mCurrentBufferSlot(-1), mCurrentBuffer(), mCurrentFence(Fence::NO_FENCE), -#ifdef USE_HWC2 mHwc(hwc), mHasPendingRelease(false), mPreviousBufferSlot(BufferQueue::INVALID_BUFFER_SLOT), mPreviousBuffer() -#else - mHwc(hwc) -#endif { -#ifdef USE_HWC2 ALOGV("Creating for display %d", disp); -#endif mName = "FramebufferSurface"; mConsumer->setConsumerName(mName); mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER); -#ifdef USE_HWC2 const auto& activeConfig = mHwc.getActiveConfig(disp); mConsumer->setDefaultBufferSize(activeConfig->getWidth(), activeConfig->getHeight()); -#else - mConsumer->setDefaultBufferFormat(mHwc.getFormat(disp)); - mConsumer->setDefaultBufferSize(mHwc.getWidth(disp), mHwc.getHeight(disp)); -#endif mConsumer->setMaxAcquiredBufferCount( SurfaceFlinger::maxFrameBufferAcquiredBuffers - 1); } @@ -98,7 +87,6 @@ status_t FramebufferSurface::prepareFrame(CompositionType /*compositionType*/) { } status_t FramebufferSurface::advanceFrame() { -#ifdef USE_HWC2 uint32_t slot = 0; sp buf; sp acquireFence(Fence::NO_FENCE); @@ -110,32 +98,18 @@ status_t FramebufferSurface::advanceFrame() { strerror(-result), result); } return result; -#else - // Once we remove FB HAL support, we can call nextBuffer() from here - // instead of using onFrameAvailable(). No real benefit, except it'll be - // more like VirtualDisplaySurface. - return NO_ERROR; -#endif } -#ifdef USE_HWC2 status_t FramebufferSurface::nextBuffer(uint32_t& outSlot, sp& outBuffer, sp& outFence, android_dataspace_t& outDataspace) { -#else -status_t FramebufferSurface::nextBuffer(sp& outBuffer, sp& outFence) { -#endif Mutex::Autolock lock(mMutex); BufferItem item; status_t err = acquireBufferLocked(&item, 0); if (err == BufferQueue::NO_BUFFER_AVAILABLE) { -#ifdef USE_HWC2 mHwcBufferCache.getHwcBuffer(mCurrentBufferSlot, mCurrentBuffer, &outSlot, &outBuffer); -#else - outBuffer = mCurrentBuffer; -#endif return NO_ERROR; } else if (err != NO_ERROR) { ALOGE("error acquiring buffer: %s (%d)", strerror(-err), err); @@ -152,26 +126,15 @@ status_t FramebufferSurface::nextBuffer(sp& outBuffer, sp& // had released the old buffer first. if (mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT && item.mSlot != mCurrentBufferSlot) { -#ifdef USE_HWC2 mHasPendingRelease = true; mPreviousBufferSlot = mCurrentBufferSlot; mPreviousBuffer = mCurrentBuffer; -#else - // Release the previous buffer. - err = releaseBufferLocked(mCurrentBufferSlot, mCurrentBuffer, - EGL_NO_DISPLAY, EGL_NO_SYNC_KHR); - if (err < NO_ERROR) { - ALOGE("error releasing buffer: %s (%d)", strerror(-err), err); - return err; - } -#endif } mCurrentBufferSlot = item.mSlot; mCurrentBuffer = mSlots[mCurrentBufferSlot].mGraphicBuffer; mCurrentFence = item.mFence; outFence = item.mFence; -#ifdef USE_HWC2 mHwcBufferCache.getHwcBuffer(mCurrentBufferSlot, mCurrentBuffer, &outSlot, &outBuffer); outDataspace = item.mDataSpace; @@ -181,31 +144,10 @@ status_t FramebufferSurface::nextBuffer(sp& outBuffer, sp& ALOGE("error posting framebuffer: %d", result); return result; } -#else - outBuffer = mCurrentBuffer; -#endif return NO_ERROR; } -#ifndef USE_HWC2 -// Overrides ConsumerBase::onFrameAvailable(), does not call base class impl. -void FramebufferSurface::onFrameAvailable(const BufferItem& /* item */) { - sp buf; - sp acquireFence; - status_t err = nextBuffer(buf, acquireFence); - if (err != NO_ERROR) { - ALOGE("error latching nnext FramebufferSurface buffer: %s (%d)", - strerror(-err), err); - return; - } - err = mHwc.fbPost(mDisplayType, acquireFence, buf); - if (err != NO_ERROR) { - ALOGE("error posting framebuffer: %d", err); - } -} -#endif - void FramebufferSurface::freeBufferLocked(int slotIndex) { ConsumerBase::freeBufferLocked(slotIndex); if (slotIndex == mCurrentBufferSlot) { @@ -214,7 +156,6 @@ void FramebufferSurface::freeBufferLocked(int slotIndex) { } void FramebufferSurface::onFrameCommitted() { -#ifdef USE_HWC2 if (mHasPendingRelease) { sp fence = mHwc.getPresentFence(mDisplayType); if (fence->isValid()) { @@ -231,24 +172,7 @@ void FramebufferSurface::onFrameCommitted() { mPreviousBuffer.clear(); mHasPendingRelease = false; } -#else - sp fence = mHwc.getAndResetReleaseFence(mDisplayType); - if (fence->isValid() && - mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT) { - status_t err = addReleaseFence(mCurrentBufferSlot, - mCurrentBuffer, fence); - ALOGE_IF(err, "setReleaseFenceFd: failed to add the fence: %s (%d)", - strerror(-err), err); - } -#endif -} - -#ifndef USE_HWC2 -status_t FramebufferSurface::compositionComplete() -{ - return mHwc.fbCompositionComplete(); } -#endif void FramebufferSurface::dumpAsString(String8& result) const { Mutex::Autolock lock(mMutex); @@ -259,9 +183,6 @@ void FramebufferSurface::dumpAsString(String8& result) const { void FramebufferSurface::dumpLocked(String8& result, const char* prefix) const { -#ifndef USE_HWC2 - mHwc.fbDump(result); -#endif ConsumerBase::dumpLocked(result, prefix); } diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h index a1756ca3c2..4186b7aac4 100644 --- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h +++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h @@ -42,9 +42,6 @@ public: virtual status_t beginFrame(bool mustRecompose); virtual status_t prepareFrame(CompositionType compositionType); -#ifndef USE_HWC2 - virtual status_t compositionComplete(); -#endif virtual status_t advanceFrame(); virtual void onFrameCommitted(); virtual void dumpAsString(String8& result) const; @@ -58,9 +55,6 @@ public: private: virtual ~FramebufferSurface() { }; // this class cannot be overloaded -#ifndef USE_HWC2 - virtual void onFrameAvailable(const BufferItem& item); -#endif virtual void freeBufferLocked(int slotIndex); virtual void dumpLocked(String8& result, const char* prefix) const; @@ -68,12 +62,8 @@ private: // nextBuffer waits for and then latches the next buffer from the // BufferQueue and releases the previously latched buffer to the // BufferQueue. The new buffer is returned in the 'buffer' argument. -#ifdef USE_HWC2 status_t nextBuffer(uint32_t& outSlot, sp& outBuffer, sp& outFence, android_dataspace_t& outDataspace); -#else - status_t nextBuffer(sp& outBuffer, sp& outFence); -#endif // mDisplayType must match one of the HWC display types int mDisplayType; @@ -100,14 +90,12 @@ private: // Hardware composer, owned by SurfaceFlinger. HWComposer& mHwc; -#ifdef USE_HWC2 HWComposerBufferCache mHwcBufferCache; // Previous buffer to release after getting an updated retire fence bool mHasPendingRelease; int mPreviousBufferSlot; sp mPreviousBuffer; -#endif }; // --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h index 3640bb5a98..3b6d931b5c 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.h +++ b/services/surfaceflinger/DisplayHardware/HWComposer.h @@ -14,10 +14,6 @@ * limitations under the License. */ -#ifndef USE_HWC2 -#include "HWComposer_hwc1.h" -#else - #ifndef ANDROID_SF_HWCOMPOSER_H #define ANDROID_SF_HWCOMPOSER_H @@ -219,5 +215,3 @@ private: }; // namespace android #endif // ANDROID_SF_HWCOMPOSER_H - -#endif // #ifdef USE_HWC2 diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp index 1de5e48cb9..dba6f7cf9a 100644 --- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp +++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp @@ -176,12 +176,6 @@ status_t VirtualDisplaySurface::prepareFrame(CompositionType compositionType) { return NO_ERROR; } -#ifndef USE_HWC2 -status_t VirtualDisplaySurface::compositionComplete() { - return NO_ERROR; -} -#endif - status_t VirtualDisplaySurface::advanceFrame() { if (mDisplayId < 0) return NO_ERROR; @@ -221,7 +215,6 @@ status_t VirtualDisplaySurface::advanceFrame() { status_t result = NO_ERROR; if (fbBuffer != NULL) { -#ifdef USE_HWC2 uint32_t hwcSlot = 0; sp hwcBuffer; mHwcBufferCache.getHwcBuffer(mFbProducerSlot, fbBuffer, @@ -230,9 +223,6 @@ status_t VirtualDisplaySurface::advanceFrame() { // TODO: Correctly propagate the dataspace from GL composition result = mHwc.setClientTarget(mDisplayId, hwcSlot, mFbFence, hwcBuffer, HAL_DATASPACE_UNKNOWN); -#else - result = mHwc.fbPost(mDisplayId, mFbFence, fbBuffer); -#endif } return result; @@ -246,22 +236,14 @@ void VirtualDisplaySurface::onFrameCommitted() { "Unexpected onFrameCommitted() in %s state", dbgStateStr()); mDbgState = DBG_STATE_IDLE; -#ifdef USE_HWC2 sp retireFence = mHwc.getPresentFence(mDisplayId); -#else - sp fbFence = mHwc.getAndResetReleaseFence(mDisplayId); -#endif if (mCompositionType == COMPOSITION_MIXED && mFbProducerSlot >= 0) { // release the scratch buffer back to the pool Mutex::Autolock lock(mMutex); int sslot = mapProducer2SourceSlot(SOURCE_SCRATCH, mFbProducerSlot); VDS_LOGV("onFrameCommitted: release scratch sslot=%d", sslot); -#ifdef USE_HWC2 addReleaseFenceLocked(sslot, mProducerBuffers[mFbProducerSlot], retireFence); -#else - addReleaseFenceLocked(sslot, mProducerBuffers[mFbProducerSlot], fbFence); -#endif releaseBufferLocked(sslot, mProducerBuffers[mFbProducerSlot], EGL_NO_DISPLAY, EGL_NO_SYNC_KHR); } @@ -269,9 +251,6 @@ void VirtualDisplaySurface::onFrameCommitted() { if (mOutputProducerSlot >= 0) { int sslot = mapProducer2SourceSlot(SOURCE_SINK, mOutputProducerSlot); QueueBufferOutput qbo; -#ifndef USE_HWC2 - sp outFence = mHwc.getLastRetireFence(mDisplayId); -#endif VDS_LOGV("onFrameCommitted: queue sink sslot=%d", sslot); if (mMustRecompose) { status_t result = mSource[SOURCE_SINK]->queueBuffer(sslot, @@ -280,11 +259,7 @@ void VirtualDisplaySurface::onFrameCommitted() { HAL_DATASPACE_UNKNOWN, Rect(mSinkBufferWidth, mSinkBufferHeight), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0 /* transform */, -#ifdef USE_HWC2 retireFence), -#else - outFence), -#endif &qbo); if (result == NO_ERROR) { updateQueueBufferOutput(std::move(qbo)); @@ -294,11 +269,7 @@ void VirtualDisplaySurface::onFrameCommitted() { // through the motions of updating the display to keep our state // machine happy. We cancel the buffer to avoid triggering another // re-composition and causing an infinite loop. -#ifdef USE_HWC2 mSource[SOURCE_SINK]->cancelBuffer(sslot, retireFence); -#else - mSource[SOURCE_SINK]->cancelBuffer(sslot, outFence); -#endif } } diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h index 1671aba1d8..5c8aceae92 100644 --- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h +++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h @@ -84,9 +84,6 @@ public: // virtual status_t beginFrame(bool mustRecompose); virtual status_t prepareFrame(CompositionType compositionType); -#ifndef USE_HWC2 - virtual status_t compositionComplete(); -#endif virtual status_t advanceFrame(); virtual void onFrameCommitted(); virtual void dumpAsString(String8& result) const; @@ -253,10 +250,7 @@ private: bool mMustRecompose; -#ifdef USE_HWC2 HWComposerBufferCache mHwcBufferCache; -#endif - bool mForceHwcCopy; }; diff --git a/services/surfaceflinger/EventControlThread.cpp b/services/surfaceflinger/EventControlThread.cpp index 052a959724..02eea4769b 100644 --- a/services/surfaceflinger/EventControlThread.cpp +++ b/services/surfaceflinger/EventControlThread.cpp @@ -53,12 +53,7 @@ bool EventControlThread::threadLoop() { } bool enable = requestedVsyncState == VsyncState::On; -#ifdef USE_HWC2 mFlinger->setVsyncEnabled(HWC_DISPLAY_PRIMARY, enable); -#else - mFlinger->eventControl(HWC_DISPLAY_PRIMARY, - SurfaceFlinger::EVENT_VSYNC, enable); -#endif currentVsyncState = requestedVsyncState; } diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 80987a4f91..aa3100eb1d 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -85,9 +85,6 @@ Layer::Layer(SurfaceFlinger* flinger, const sp& client, const String8& n mFiltering(false), mNeedsFiltering(false), mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2), -#ifndef USE_HWC2 - mIsGlesComposition(false), -#endif mProtectedByApp(false), mClientRef(client), mPotentialCursor(false), @@ -128,13 +125,9 @@ Layer::Layer(SurfaceFlinger* flinger, const sp& client, const String8& n // drawing state & current state are identical mDrawingState = mCurrentState; -#ifdef USE_HWC2 const auto& hwc = flinger->getHwComposer(); const auto& activeConfig = hwc.getActiveConfig(HWC_DISPLAY_PRIMARY); nsecs_t displayPeriod = activeConfig->getVsyncPeriod(); -#else - nsecs_t displayPeriod = flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY); -#endif mFrameTracker.setDisplayRefreshPeriod(displayPeriod); CompositorTiming compositorTiming; @@ -157,12 +150,7 @@ Layer::~Layer() { * Layer. So, the implementation is done in BufferLayer. When called on a * ColorLayer object, it's essentially a NOP. */ -#ifdef USE_HWC2 void Layer::onLayerDisplayed(const sp& /*releaseFence*/) {} -#else -void Layer::onLayerDisplayed(const sp& /* hw */, - HWComposer::HWCLayerInterface* /*layer*/) {} -#endif void Layer::onRemovedFromCurrentState() { // the layer is removed from SF mCurrentState to mLayersPendingRemoval @@ -187,9 +175,7 @@ void Layer::onRemoved() { // the layer is removed from SF mLayersPendingRemoval abandon(); -#ifdef USE_HWC2 destroyAllHwcLayers(); -#endif for (const auto& child : mCurrentChildren) { child->onRemoved(); @@ -217,7 +203,6 @@ sp Layer::getHandle() { // h/w composer set-up // --------------------------------------------------------------------------- -#ifdef USE_HWC2 bool Layer::createHwcLayer(HWComposer* hwc, int32_t hwcId) { LOG_ALWAYS_FATAL_IF(mHwcLayers.count(hwcId) != 0, "Already have a layer for hwcId %d", hwcId); HWC2::Layer* layer = hwc->createLayer(hwcId); @@ -254,7 +239,6 @@ void Layer::destroyAllHwcLayers() { LOG_ALWAYS_FATAL_IF(!mHwcLayers.empty(), "All hardware composer layers should have been destroyed"); } -#endif Rect Layer::getContentCrop() const { // this is the crop rectangle that applies to the buffer @@ -470,21 +454,12 @@ FloatRect Layer::computeCrop(const sp& hw) const { return crop; } -#ifdef USE_HWC2 void Layer::setGeometry(const sp& displayDevice, uint32_t z) -#else -void Layer::setGeometry(const sp& hw, HWComposer::HWCLayerInterface& layer) -#endif { -#ifdef USE_HWC2 const auto hwcId = displayDevice->getHwcDisplayId(); auto& hwcInfo = mHwcLayers[hwcId]; -#else - layer.setDefaultState(); -#endif // enable this layer -#ifdef USE_HWC2 hwcInfo.forceClientComposition = false; if (isSecure() && !displayDevice->isSecure()) { @@ -492,17 +467,9 @@ void Layer::setGeometry(const sp& hw, HWComposer::HWCLayerI } auto& hwcLayer = hwcInfo.layer; -#else - layer.setSkip(false); - - if (isSecure() && !hw->isSecure()) { - layer.setSkip(true); - } -#endif // this gives us only the "orientation" component of the transform const State& s(getDrawingState()); -#ifdef USE_HWC2 auto blendMode = HWC2::BlendMode::None; if (!isOpaque(s) || getAlpha() != 1.0f) { blendMode = @@ -514,11 +481,6 @@ void Layer::setGeometry(const sp& hw, HWComposer::HWCLayerI " %s (%d)", mName.string(), to_string(blendMode).c_str(), to_string(error).c_str(), static_cast(error)); -#else - if (!isOpaque(s) || getAlpha() != 1.0f) { - layer.setBlending(mPremultipliedAlpha ? HWC_BLENDING_PREMULT : HWC_BLENDING_COVERAGE); - } -#endif // apply the layer's transform, followed by the display's global transform // here we're guaranteed that the layer's transform preserves rects @@ -527,11 +489,7 @@ void Layer::setGeometry(const sp& hw, HWComposer::HWCLayerI if (!s.crop.isEmpty()) { Rect activeCrop(s.crop); activeCrop = t.transform(activeCrop); -#ifdef USE_HWC2 if (!activeCrop.intersect(displayDevice->getViewport(), &activeCrop)) { -#else - if (!activeCrop.intersect(hw->getViewport(), &activeCrop)) { -#endif activeCrop.clear(); } activeCrop = t.inverse().transform(activeCrop, true); @@ -558,7 +516,6 @@ void Layer::setGeometry(const sp& hw, HWComposer::HWCLayerI frame.clear(); } } -#ifdef USE_HWC2 if (!frame.intersect(displayDevice->getViewport(), &frame)) { frame.clear(); } @@ -607,15 +564,6 @@ void Layer::setGeometry(const sp& hw, HWComposer::HWCLayerI error = hwcLayer->setInfo(type, appId); ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set info (%d)", mName.string(), static_cast(error)); -#else - if (!frame.intersect(hw->getViewport(), &frame)) { - frame.clear(); - } - const Transform& tr(hw->getTransform()); - layer.setFrame(tr.transform(frame)); - layer.setCrop(computeCrop(hw)); - layer.setPlaneAlpha(static_cast(std::round(255.0f * getAlpha()))); -#endif /* * Transformations are applied in this order: @@ -650,7 +598,6 @@ void Layer::setGeometry(const sp& hw, HWComposer::HWCLayerI // this gives us only the "orientation" component of the transform const uint32_t orientation = transform.getOrientation(); -#ifdef USE_HWC2 if (orientation & Transform::ROT_INVALID) { // we can only handle simple transformation hwcInfo.forceClientComposition = true; @@ -663,17 +610,8 @@ void Layer::setGeometry(const sp& hw, HWComposer::HWCLayerI mName.string(), to_string(transform).c_str(), to_string(error).c_str(), static_cast(error)); } -#else - if (orientation & Transform::ROT_INVALID) { - // we can only handle simple transformation - layer.setSkip(true); - } else { - layer.setTransform(orientation); - } -#endif } -#ifdef USE_HWC2 void Layer::forceClientComposition(int32_t hwcId) { if (mHwcLayers.count(hwcId) == 0) { ALOGE("forceClientComposition: no HWC layer found (%d)", hwcId); @@ -682,32 +620,7 @@ void Layer::forceClientComposition(int32_t hwcId) { mHwcLayers[hwcId].forceClientComposition = true; } -#else -void Layer::setPerFrameData(const sp& hw, - HWComposer::HWCLayerInterface& layer) { - // we have to set the visible region on every frame because - // we currently free it during onLayerDisplayed(), which is called - // after HWComposer::commit() -- every frame. - // Apply this display's projection's viewport to the visible region - // before giving it to the HWC HAL. - const Transform& tr = hw->getTransform(); - Region visible = tr.transform(visibleRegion.intersect(hw->getViewport())); - layer.setVisibleRegionScreen(visible); - layer.setSurfaceDamage(surfaceDamageRegion); - mIsGlesComposition = (layer.getCompositionType() == HWC_FRAMEBUFFER); - - if (mSidebandStream.get()) { - layer.setSidebandStream(mSidebandStream); - } else { - // NOTE: buffer can be NULL if the client never drew into this - // layer yet, or if we ran out of memory - layer.setBuffer(mActiveBuffer); - } -} -#endif - -#ifdef USE_HWC2 void Layer::updateCursorPosition(const sp& displayDevice) { auto hwcId = displayDevice->getHwcDisplayId(); if (mHwcLayers.count(hwcId) == 0 || getCompositionType(hwcId) != HWC2::Composition::Cursor) { @@ -740,28 +653,6 @@ void Layer::updateCursorPosition(const sp& displayDevice) { mName.string(), position.left, position.top, to_string(error).c_str(), static_cast(error)); } -#else -Rect Layer::getPosition(const sp& hw) { - // this gives us only the "orientation" component of the transform - const State& s(getCurrentState()); - - // apply the layer's transform, followed by the display's global transform - // here we're guaranteed that the layer's transform preserves rects - Rect win(s.active.w, s.active.h); - if (!s.crop.isEmpty()) { - win.intersect(s.crop, &win); - } - // subtract the transparent region and snap to the bounds - Rect bounds = reduce(win, s.activeTransparentRegion); - Rect frame(getTransform().transform(bounds)); - frame.intersect(hw->getViewport(), &frame); - if (!s.finalCrop.isEmpty()) { - frame.intersect(s.finalCrop, &frame); - } - const Transform& tr(hw->getTransform()); - return Rect(tr.transform(frame)); -} -#endif // --------------------------------------------------------------------------- // drawing... @@ -791,7 +682,6 @@ void Layer::clearWithOpenGL(const RenderArea& renderArea) const { clearWithOpenGL(renderArea, 0, 0, 0, 0); } -#ifdef USE_HWC2 void Layer::setCompositionType(int32_t hwcId, HWC2::Composition type, bool callIntoHwc) { if (mHwcLayers.count(hwcId) == 0) { ALOGE("setCompositionType called without a valid HWC layer"); @@ -843,7 +733,6 @@ bool Layer::getClearClientTarget(int32_t hwcId) const { } return mHwcLayers.at(hwcId).clearClientTarget; } -#endif bool Layer::addSyncPoint(const std::shared_ptr& point) { if (point->getFrameNumber() <= mCurrentFrameNumber) { @@ -1496,7 +1385,7 @@ LayerDebugInfo Layer::getLayerDebugInfo() const { info.mContentDirty = contentDirty; return info; } -#ifdef USE_HWC2 + void Layer::miniDumpHeader(String8& result) { result.append("----------------------------------------"); result.append("---------------------------------------\n"); @@ -1539,7 +1428,6 @@ void Layer::miniDump(String8& result, int32_t hwcId) const { result.append("- - - - - - - - - - - - - - - - - - - - "); result.append("- - - - - - - - - - - - - - - - - - - -\n"); } -#endif void Layer::dumpFrameStats(String8& result) const { mFrameTracker.dumpStats(result); diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 0580b9f40f..c125a3c3e1 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -297,7 +297,6 @@ protected: public: virtual void setDefaultBufferSize(uint32_t w, uint32_t h) = 0; -#ifdef USE_HWC2 void setGeometry(const sp& displayDevice, uint32_t z); void forceClientComposition(int32_t hwcId); virtual void setPerFrameData(const sp& displayDevice) = 0; @@ -309,23 +308,11 @@ public: void setClearClientTarget(int32_t hwcId, bool clear); bool getClearClientTarget(int32_t hwcId) const; void updateCursorPosition(const sp& hw); -#else - void setGeometry(const sp& hw, HWComposer::HWCLayerInterface& layer); - void setPerFrameData(const sp& hw, HWComposer::HWCLayerInterface& layer); - virtual void setAcquireFence(const sp& hw, - HWComposer::HWCLayerInterface& layer) = 0; - Rect getPosition(const sp& hw); -#endif /* * called after page-flip */ -#ifdef USE_HWC2 virtual void onLayerDisplayed(const sp& releaseFence); -#else - virtual void onLayerDisplayed(const sp& hw, - HWComposer::HWCLayerInterface* layer); -#endif virtual void abandon() = 0; @@ -346,10 +333,8 @@ public: const std::shared_ptr& presentFence, const CompositorTiming& compositorTiming) = 0; -#ifdef USE_HWC2 // If a buffer was replaced this frame, release the former buffer virtual void releasePendingBuffer(nsecs_t dequeueReadyTime) = 0; -#endif /* * draw - performs some global clipping optimizations @@ -425,7 +410,6 @@ public: int32_t getQueuedFrameCount() const { return mQueuedFrames; } -#ifdef USE_HWC2 // ----------------------------------------------------------------------- bool createHwcLayer(HWComposer* hwc, int32_t hwcId); @@ -441,7 +425,6 @@ public: return mHwcLayers[hwcId].layer; } -#endif // ----------------------------------------------------------------------- void clearWithOpenGL(const RenderArea& renderArea) const; @@ -458,10 +441,8 @@ public: LayerDebugInfo getLayerDebugInfo() const; /* always call base class first */ -#ifdef USE_HWC2 static void miniDumpHeader(String8& result); void miniDump(String8& result, int32_t hwcId) const; -#endif void dumpFrameStats(String8& result) const; void dumpFrameEvents(String8& result); void clearFrameStats(); @@ -673,7 +654,6 @@ protected: bool mPendingRemoval = false; -#ifdef USE_HWC2 // HWC items, accessed from the main thread struct HWCInfo { HWCInfo() @@ -698,9 +678,6 @@ protected: // case we need to keep track. In non-mirror mode, a layer will have only one // HWCInfo. This map key is a display layerStack. std::unordered_map mHwcLayers; -#else - bool mIsGlesComposition; -#endif // page-flip thread (currently main thread) bool mProtectedByApp; // application requires protected path to external sink diff --git a/services/surfaceflinger/RenderArea.h b/services/surfaceflinger/RenderArea.h index faf1ec64f8..44b9dc9254 100644 --- a/services/surfaceflinger/RenderArea.h +++ b/services/surfaceflinger/RenderArea.h @@ -24,10 +24,8 @@ public: int getReqHeight() const { return mReqHeight; }; int getReqWidth() const { return mReqWidth; }; Transform::orientation_flags getRotationFlags() const { return mRotationFlags; }; -#ifdef USE_HWC2 virtual bool getWideColorSupport() const = 0; virtual android_color_mode_t getActiveColorMode() const = 0; -#endif status_t updateDimensions(); @@ -37,4 +35,4 @@ private: Transform::orientation_flags mRotationFlags; }; -} // namespace android \ No newline at end of file +} // namespace android diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp index daaa11e1d3..3ae7042230 100644 --- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp +++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp @@ -44,7 +44,6 @@ #include // --------------------------------------------------------------------------- -#ifdef USE_HWC2 bool checkGlError(const char* op, int lineNumber) { bool errorFound = false; GLint error = glGetError(); @@ -103,7 +102,6 @@ void writePPM(const char* basename, GLuint width, GLuint height) { } file.write(reinterpret_cast(outBuffer.data()), outBuffer.size()); } -#endif // --------------------------------------------------------------------------- namespace android { @@ -132,7 +130,6 @@ GLES20RenderEngine::GLES20RenderEngine(uint32_t featureFlags) : //mColorBlindnessCorrection = M; -#ifdef USE_HWC2 if (mPlatformHasWideColor) { // Compute sRGB to DisplayP3 color transform // NOTE: For now, we are limiting wide-color support to @@ -145,7 +142,6 @@ GLES20RenderEngine::GLES20RenderEngine(uint32_t featureFlags) : mat4 gamutTransform(srgbToP3); mSrgbToDisplayP3 = gamutTransform; } -#endif } GLES20RenderEngine::~GLES20RenderEngine() { @@ -222,7 +218,6 @@ void GLES20RenderEngine::setupLayerBlending(bool premultipliedAlpha, } } -#ifdef USE_HWC2 void GLES20RenderEngine::setColorMode(android_color_mode mode) { ALOGV("setColorMode: %s (0x%x)", decodeColorMode(mode).c_str(), mode); @@ -256,7 +251,6 @@ void GLES20RenderEngine::setWideColor(bool hasWideColor) { bool GLES20RenderEngine::usesWideColor() { return mUseWideColor; } -#endif void GLES20RenderEngine::setupLayerTexturing(const Texture& texture) { GLuint target = texture.getTextureTarget(); @@ -344,7 +338,6 @@ void GLES20RenderEngine::drawMesh(const Mesh& mesh) { mesh.getByteStride(), mesh.getPositions()); -#ifdef USE_HWC2 if (usesWideColor()) { Description wideColorState = mState; if (mDataSpace != HAL_DATASPACE_DISPLAY_P3) { @@ -366,11 +359,6 @@ void GLES20RenderEngine::drawMesh(const Mesh& mesh) { glDrawArrays(mesh.getPrimitive(), 0, mesh.getVertexCount()); } -#else - ProgramCache::getInstance().useProgram(mState); - - glDrawArrays(mesh.getPrimitive(), 0, mesh.getVertexCount()); -#endif if (mesh.getTexCoordsSize()) { glDisableVertexAttribArray(Program::texCoords); @@ -379,13 +367,11 @@ void GLES20RenderEngine::drawMesh(const Mesh& mesh) { void GLES20RenderEngine::dump(String8& result) { RenderEngine::dump(result); -#ifdef USE_HWC2 if (usesWideColor()) { result.append("Wide-color: On\n"); } else { result.append("Wide-color: Off\n"); } -#endif } // --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h index 5ac12fc3d6..b96bfe0f99 100644 --- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h +++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h @@ -70,7 +70,6 @@ protected: Transform::orientation_flags rotation); virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, bool disableTexture, const half4& color) override; -#ifdef USE_HWC2 // Color management related functions and state void setColorMode(android_color_mode mode); @@ -91,7 +90,6 @@ protected: // Currently only supporting sRGB and DisplayP3 color spaces mat4 mSrgbToDisplayP3; -#endif bool mPlatformHasWideColor = false; virtual void setupLayerTexturing(const Texture& texture); diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.h b/services/surfaceflinger/RenderEngine/RenderEngine.h index fa65979edd..7e05cec7d6 100644 --- a/services/surfaceflinger/RenderEngine/RenderEngine.h +++ b/services/surfaceflinger/RenderEngine/RenderEngine.h @@ -101,12 +101,10 @@ public: Rect sourceCrop, size_t hwh, bool yswap, Transform::orientation_flags rotation) = 0; virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, bool disableTexture, const half4& color) = 0; -#ifdef USE_HWC2 virtual void setColorMode(android_color_mode mode) = 0; virtual void setSourceDataSpace(android_dataspace source) = 0; virtual void setWideColor(bool hasWideColor) = 0; virtual bool usesWideColor() = 0; -#endif virtual void setupLayerTexturing(const Texture& texture) = 0; virtual void setupLayerBlackedOut() = 0; virtual void setupFillWithColor(float r, float g, float b, float a) = 0; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index d13b188ab8..96ba5fb766 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -2675,12 +2675,10 @@ bool SurfaceFlinger::doComposeSurfaces( if (hasClientComposition) { ALOGV("hasClientComposition"); -#ifdef USE_HWC2 mRenderEngine->setWideColor( displayDevice->getWideColorSupport() && !mForceNativeColorMode); mRenderEngine->setColorMode(mForceNativeColorMode ? HAL_COLOR_MODE_NATIVE : displayDevice->getActiveColorMode()); -#endif if (!displayDevice->makeCurrent(mEGLDisplay, mEGLContext)) { ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s", displayDevice->getDisplayName().string()); diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index d10b41bd34..67e4607012 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -63,12 +63,8 @@ #include "SurfaceTracing.h" #include "StartPropertySetThread.h" -#ifdef USE_HWC2 #include "DisplayHardware/HWC2.h" #include "DisplayHardware/HWComposer.h" -#else -#include "DisplayHardware/HWComposer_hwc1.h" -#endif #include "Effects/Daltonizer.h" @@ -117,11 +113,7 @@ enum { class SurfaceFlinger : public BnSurfaceComposer, public PriorityDumper, private IBinder::DeathRecipient, -#ifdef USE_HWC2 private HWC2::ComposerCallback -#else - private HWComposer::EventHandler -#endif { public: @@ -217,11 +209,7 @@ public: // enable/disable h/w composer event // TODO: this should be made accessible only to EventThread -#ifdef USE_HWC2 void setVsyncEnabled(int disp, int enabled); -#else - void eventControl(int disp, int event, int enabled); -#endif // called on the main thread by MessageQueue when an internal message // is received @@ -344,18 +332,12 @@ private: /* ------------------------------------------------------------------------ * HWC2::ComposerCallback / HWComposer::EventHandler interface */ -#ifdef USE_HWC2 void onVsyncReceived(int32_t sequenceId, hwc2_display_t display, int64_t timestamp) override; void onHotplugReceived(int32_t sequenceId, hwc2_display_t display, HWC2::Connection connection, bool primaryDisplay) override; void onRefreshReceived(int32_t sequenceId, hwc2_display_t display) override; -#else - void onVSyncReceived(HWComposer* composer, int type, nsecs_t timestamp) override; - void onHotplugReceived(HWComposer* composer, int disp, bool connected) override; - void onInvalidateReceived(HWComposer* composer) override; -#endif /* ------------------------------------------------------------------------ * Message handling @@ -372,12 +354,8 @@ private: // called on the main thread in response to setActiveConfig() void setActiveConfigInternal(const sp& hw, int mode); // called on the main thread in response to setPowerMode() -#ifdef USE_HWC2 void setPowerModeInternal(const sp& hw, int mode, bool stateLockHeld); -#else - void setPowerModeInternal(const sp& hw, int mode); -#endif // Called on the main thread in response to setActiveColorMode() void setActiveColorModeInternal(const sp& hw, android_color_mode_t colorMode); @@ -463,17 +441,10 @@ private: const sp& producer, bool useIdentityTransform); -#ifdef USE_HWC2 status_t captureScreenImplLocked(const RenderArea& renderArea, TraverseLayersFunction traverseLayers, ANativeWindowBuffer* buffer, bool useIdentityTransform, bool isLocalScreenshot, int* outSyncFd); -#else - status_t captureScreenImplLocked(const RenderArea& renderArea, - TraverseLayersFunction traverseLayers, - const sp& producer, - bool useIdentityTransform, bool isLocalScreenshot); -#endif void traverseLayersInDisplay(const sp& display, int32_t minLayerZ, int32_t maxLayerZ, const LayerVector::Visitor& visitor); @@ -540,10 +511,6 @@ private: // region of all screens presenting this layer stack. void invalidateLayerStack(const sp& layer, const Region& dirty); -#ifndef USE_HWC2 - int32_t allocateHwcDisplayId(DisplayDevice::DisplayType type); -#endif - /* ------------------------------------------------------------------------ * H/W composer */ @@ -642,7 +609,6 @@ private: } status_t doDump(int fd, const Vector& args, bool asProto); -#ifdef USE_HWC2 /* ------------------------------------------------------------------------ * VrFlinger */ @@ -650,7 +616,6 @@ private: // Check to see if we should handoff to vr flinger. void updateVrFlinger(); -#endif /* ------------------------------------------------------------------------ * Attributes @@ -695,9 +660,7 @@ private: // acquiring mStateLock. std::unique_ptr mHwc; -#ifdef USE_HWC2 const std::string mHwcServiceName; // "default" for real use, something else for testing. -#endif // constant members (no synchronization needed for access) RenderEngine* mRenderEngine; @@ -716,17 +679,11 @@ private: // don't need synchronization State mDrawingState{LayerVector::StateSet::Drawing}; bool mVisibleRegionsDirty; -#ifndef USE_HWC2 - bool mHwWorkListDirty; -#else bool mGeometryInvalid; -#endif bool mAnimCompositionPending; -#ifdef USE_HWC2 std::vector> mLayersWithQueuedFrames; sp mPreviousPresentFence = Fence::NO_FENCE; bool mHadClientComposition = false; -#endif FenceTimeline mGlCompositionDoneTimeline; FenceTimeline mDisplayTimeline; @@ -745,9 +702,7 @@ private: nsecs_t mLastTransactionTime; bool mBootFinished; bool mForceFullDamage; -#ifdef USE_HWC2 bool mPropagateBackpressure = true; -#endif SurfaceInterceptor mInterceptor; SurfaceTracing mTracing; bool mUseHwcVirtualDisplays = false; @@ -789,9 +744,6 @@ private: bool mInjectVSyncs; Daltonizer mDaltonizer; -#ifndef USE_HWC2 - bool mDaltonize; -#endif mat4 mPreviousColorMatrix; mat4 mColorMatrix; @@ -833,7 +785,6 @@ private: // either AID_GRAPHICS or AID_SYSTEM. status_t CheckTransactCodeCredentials(uint32_t code); -#ifdef USE_HWC2 std::unique_ptr mVrFlinger; std::atomic mVrFlingerRequestsDisplay; static bool useVrFlinger; @@ -842,7 +793,6 @@ private: // use to differentiate callbacks from different hardware composer // instances. Each hardware composer instance gets a different sequence id. int32_t mComposerSequenceId; -#endif float mSaturation = 1.0f; bool mForceNativeColorMode = false; diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.cpp b/services/surfaceflinger/SurfaceFlingerConsumer.cpp index abc8fde26b..e17bb58b31 100644 --- a/services/surfaceflinger/SurfaceFlingerConsumer.cpp +++ b/services/surfaceflinger/SurfaceFlingerConsumer.cpp @@ -89,11 +89,7 @@ status_t SurfaceFlingerConsumer::updateTexImage(BufferRejecter* rejecter, } // Release the previous buffer. -#ifdef USE_HWC2 err = updateAndReleaseLocked(item, &mPendingRelease); -#else - err = updateAndReleaseLocked(item); -#endif if (err != NO_ERROR) { return err; } @@ -197,7 +193,6 @@ sp SurfaceFlingerConsumer::getPrevFinalReleaseFence() const { return ConsumerBase::mPrevFinalReleaseFence; } -#ifdef USE_HWC2 void SurfaceFlingerConsumer::setReleaseFence(const sp& fence) { if (!mPendingRelease.isPending) { @@ -230,7 +225,6 @@ bool SurfaceFlingerConsumer::releasePendingBuffer() mPendingRelease = PendingRelease(); return true; } -#endif void SurfaceFlingerConsumer::setContentsChangedListener( const wp& listener) { diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.h b/services/surfaceflinger/SurfaceFlingerConsumer.h index 1126233d60..53b4915426 100644 --- a/services/surfaceflinger/SurfaceFlingerConsumer.h +++ b/services/surfaceflinger/SurfaceFlingerConsumer.h @@ -81,10 +81,8 @@ public: nsecs_t computeExpectedPresent(const DispSync& dispSync); sp getPrevFinalReleaseFence() const; -#ifdef USE_HWC2 virtual void setReleaseFence(const sp& fence) override; bool releasePendingBuffer(); -#endif void onDisconnect() override; void addAndGetFrameTimestamps( @@ -104,11 +102,9 @@ private: // The portion of this surface that has changed since the previous frame Region mSurfaceDamage; -#ifdef USE_HWC2 // A release that is pending on the receipt of a new release fence from // presentDisplay PendingRelease mPendingRelease; -#endif // The layer for this SurfaceFlingerConsumer const wp mLayer; diff --git a/services/surfaceflinger/tests/fakehwc/FakeComposerClient.h b/services/surfaceflinger/tests/fakehwc/FakeComposerClient.h index 2a5a8ad03f..b94418281e 100644 --- a/services/surfaceflinger/tests/fakehwc/FakeComposerClient.h +++ b/services/surfaceflinger/tests/fakehwc/FakeComposerClient.h @@ -16,7 +16,11 @@ #pragma once +#define HWC2_USE_CPP11 +#define HWC2_INCLUDE_STRINGIFICATION #include "ComposerClient.h" +#undef HWC2_USE_CPP11 +#undef HWC2_INCLUDE_STRINGIFICATION #include "RenderState.h" // Needed for display type/ID enums -- cgit v1.2.3-59-g8ed1b From c9232edd34618360d099272fb0537cae2f715860 Mon Sep 17 00:00:00 2001 From: chaviw Date: Tue, 14 Nov 2017 15:31:15 -0800 Subject: Added check for forceClientComposition for every layer. Instead of having the Layers check for forceClientComposition, have SurfaceFlinger check since it will be skipping hwc. This also ensures that new Layer types also get the same check. Fixes: 69254085 Test: Current tests pass. Rotation works correctly now. Change-Id: I7a2a378d9690206008b1dab9ce521f959542903a --- services/surfaceflinger/BufferLayer.cpp | 8 -------- services/surfaceflinger/Layer.cpp | 9 +++++++++ services/surfaceflinger/Layer.h | 1 + services/surfaceflinger/SurfaceFlinger.cpp | 6 ++++++ 4 files changed, 16 insertions(+), 8 deletions(-) (limited to 'services/surfaceflinger/BufferLayer.cpp') diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index 0c1693b53b..c477a3b190 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -613,14 +613,6 @@ void BufferLayer::setPerFrameData(const sp& displayDevice) return; } - // Client layers - if (hwcInfo.forceClientComposition || - (mActiveBuffer != nullptr && mActiveBuffer->handle == nullptr)) { - ALOGV("[%s] Requesting Client composition", mName.string()); - setCompositionType(hwcId, HWC2::Composition::Client); - return; - } - // Device or Cursor layers if (mPotentialCursor) { ALOGV("[%s] Requesting Cursor composition", mName.string()); diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index aa3100eb1d..50e2c6f55c 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -621,6 +621,15 @@ void Layer::forceClientComposition(int32_t hwcId) { mHwcLayers[hwcId].forceClientComposition = true; } +bool Layer::getForceClientComposition(int32_t hwcId) { + if (mHwcLayers.count(hwcId) == 0) { + ALOGE("getForceClientComposition: no HWC layer found (%d)", hwcId); + return false; + } + + return mHwcLayers[hwcId].forceClientComposition; +} + void Layer::updateCursorPosition(const sp& displayDevice) { auto hwcId = displayDevice->getHwcDisplayId(); if (mHwcLayers.count(hwcId) == 0 || getCompositionType(hwcId) != HWC2::Composition::Cursor) { diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index c125a3c3e1..0fc5ad55d2 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -299,6 +299,7 @@ public: void setGeometry(const sp& displayDevice, uint32_t z); void forceClientComposition(int32_t hwcId); + bool getForceClientComposition(int32_t hwcId); virtual void setPerFrameData(const sp& displayDevice) = 0; // callIntoHwc exists so we can update our local state and call diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 96ba5fb766..1237ee4320 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -1956,6 +1956,12 @@ void SurfaceFlinger::setUpHWComposer() { "display %zd: %d", displayId, result); } for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { + if (layer->getForceClientComposition(hwcId)) { + ALOGV("[%s] Requesting Client composition", layer->getName().string()); + layer->setCompositionType(hwcId, HWC2::Composition::Client); + continue; + } + layer->setPerFrameData(displayDevice); } -- cgit v1.2.3-59-g8ed1b From 83806897c6366d841971a38f4a007bb83a7afb64 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Thu, 16 Nov 2017 10:50:20 -0800 Subject: surfaceflinger: fix fencing when layers become invisible A layer always holds on to a buffer (after the first one is acquired). When a new buffer comes in, and the layer is visible, it will - acquire the new buffer - present the new buffer to HWC - get the release fence from HWC - associate the old buffer with the release fence and release it But if the layer happens to be becoming invisible, it will go through - acquire the new buffer - destroy the HWC layer and present - release the old buffer without any fence The problem here is that the old buffer is still on screen until the present takes effect (e.g., on next HW vsync). Rendering artifacts may be seen on screen. This commit changes the acquire/release process for layer becoming invisible to - acquire the new buffer - destroy the HWC layer and present - get a fence from HWC - associate the old buffer with the fence and release it We do not require HWC getReleaseFences to return fences for destroyed layers. We can only use the next best fence, the present fence. Bug: 68490054 Test: manual Change-Id: I68bbf392a6681c6512fc0be68a7d17df122f7308 --- services/surfaceflinger/BufferLayer.cpp | 3 --- services/surfaceflinger/DisplayDevice.cpp | 8 ++++++++ services/surfaceflinger/DisplayDevice.h | 4 ++++ services/surfaceflinger/Layer.cpp | 6 ++++-- services/surfaceflinger/Layer.h | 2 +- services/surfaceflinger/SurfaceFlinger.cpp | 31 ++++++++++++++++++++++++++++-- 6 files changed, 46 insertions(+), 8 deletions(-) (limited to 'services/surfaceflinger/BufferLayer.cpp') diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index c477a3b190..4e214d1b74 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -262,9 +262,6 @@ void BufferLayer::onDraw(const RenderArea& renderArea, const Region& clip, } void BufferLayer::onLayerDisplayed(const sp& releaseFence) { - if (mHwcLayers.empty()) { - return; - } mSurfaceFlingerConsumer->setReleaseFence(releaseFence); } diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp index ef7d482f28..6d6781e4d4 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -325,6 +325,14 @@ const Vector< sp >& DisplayDevice::getVisibleLayersSortedByZ() const { return mVisibleLayersSortedByZ; } +void DisplayDevice::setLayersNeedingFences(const Vector< sp >& layers) { + mLayersNeedingFences = layers; +} + +const Vector< sp >& DisplayDevice::getLayersNeedingFences() const { + return mLayersNeedingFences; +} + Region DisplayDevice::getDirtyRegion(bool repaintEverything) const { Region dirty; if (repaintEverything) { diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h index 50e30b2571..e388a5b2c3 100644 --- a/services/surfaceflinger/DisplayDevice.h +++ b/services/surfaceflinger/DisplayDevice.h @@ -113,6 +113,8 @@ public: void setVisibleLayersSortedByZ(const Vector< sp >& layers); const Vector< sp >& getVisibleLayersSortedByZ() const; + void setLayersNeedingFences(const Vector< sp >& layers); + const Vector< sp >& getLayersNeedingFences() const; Region getDirtyRegion(bool repaintEverything) const; void setLayerStack(uint32_t stack); @@ -214,6 +216,8 @@ private: // list of visible layers on that display Vector< sp > mVisibleLayersSortedByZ; + // list of layers needing fences + Vector< sp > mLayersNeedingFences; /* * Transaction state diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 50e2c6f55c..abf25ec117 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -217,9 +217,9 @@ bool Layer::createHwcLayer(HWComposer* hwc, int32_t hwcId) { return true; } -void Layer::destroyHwcLayer(int32_t hwcId) { +bool Layer::destroyHwcLayer(int32_t hwcId) { if (mHwcLayers.count(hwcId) == 0) { - return; + return false; } auto& hwcInfo = mHwcLayers[hwcId]; LOG_ALWAYS_FATAL_IF(hwcInfo.layer == nullptr, "Attempt to destroy null layer"); @@ -228,6 +228,8 @@ void Layer::destroyHwcLayer(int32_t hwcId) { // The layer destroyed listener should have cleared the entry from // mHwcLayers. Verify that. LOG_ALWAYS_FATAL_IF(mHwcLayers.count(hwcId) != 0, "Stale layer entry in mHwcLayers"); + + return true; } void Layer::destroyAllHwcLayers() { diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 0fc5ad55d2..44b178a71b 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -414,7 +414,7 @@ public: // ----------------------------------------------------------------------- bool createHwcLayer(HWComposer* hwc, int32_t hwcId); - void destroyHwcLayer(int32_t hwcId); + bool destroyHwcLayer(int32_t hwcId); void destroyAllHwcLayers(); bool hasHwcLayer(int32_t hwcId) { return mHwcLayers.count(hwcId) > 0; } diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 1237ee4320..4e73bfa6b7 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -1781,6 +1781,7 @@ void SurfaceFlinger::rebuildLayerStacks() { Region opaqueRegion; Region dirtyRegion; Vector> layersSortedByZ; + Vector> layersNeedingFences; const sp& displayDevice(mDisplays[dpy]); const Transform& tr(displayDevice->getTransform()); const Rect bounds(displayDevice->getBounds()); @@ -1788,6 +1789,7 @@ void SurfaceFlinger::rebuildLayerStacks() { computeVisibleRegions(displayDevice, dirtyRegion, opaqueRegion); mDrawingState.traverseInZOrder([&](Layer* layer) { + bool hwcLayerDestroyed = false; if (layer->belongsToDisplay(displayDevice->getLayerStack(), displayDevice->isPrimary())) { Region drawRegion(tr.transform( @@ -1798,18 +1800,32 @@ void SurfaceFlinger::rebuildLayerStacks() { } else { // Clear out the HWC layer if this layer was // previously visible, but no longer is - layer->destroyHwcLayer( + hwcLayerDestroyed = layer->destroyHwcLayer( displayDevice->getHwcDisplayId()); } } else { // WM changes displayDevice->layerStack upon sleep/awake. // Here we make sure we delete the HWC layers even if // WM changed their layer stack. - layer->destroyHwcLayer(displayDevice->getHwcDisplayId()); + hwcLayerDestroyed = layer->destroyHwcLayer( + displayDevice->getHwcDisplayId()); + } + + // If a layer is not going to get a release fence because + // it is invisible, but it is also going to release its + // old buffer, add it to the list of layers needing + // fences. + if (hwcLayerDestroyed) { + auto found = std::find(mLayersWithQueuedFrames.cbegin(), + mLayersWithQueuedFrames.cend(), layer); + if (found != mLayersWithQueuedFrames.cend()) { + layersNeedingFences.add(layer); + } } }); } displayDevice->setVisibleLayersSortedByZ(layersSortedByZ); + displayDevice->setLayersNeedingFences(layersNeedingFences); displayDevice->undefinedRegion.set(bounds); displayDevice->undefinedRegion.subtractSelf( tr.transform(opaqueRegion)); @@ -2046,6 +2062,17 @@ void SurfaceFlinger::postFramebuffer() } layer->onLayerDisplayed(releaseFence); } + + // We've got a list of layers needing fences, that are disjoint with + // displayDevice->getVisibleLayersSortedByZ. The best we can do is to + // supply them with the present fence. + if (!displayDevice->getLayersNeedingFences().isEmpty()) { + sp presentFence = mHwc->getPresentFence(hwcId); + for (auto& layer : displayDevice->getLayersNeedingFences()) { + layer->onLayerDisplayed(presentFence); + } + } + if (hwcId >= 0) { mHwc->clearReleaseFences(hwcId); } -- cgit v1.2.3-59-g8ed1b From 9eeae69005ef9a774bde19195b9c06eba7e463c2 Mon Sep 17 00:00:00 2001 From: David Sodman Date: Thu, 2 Nov 2017 10:53:32 -0700 Subject: Surfaceflinger: Create LayerBE data class Split Layer class into a backend and front-end version. This change creates the backend struct and only puts a single data item in that struct. Follow-on changes to move more things to the backend will follow Test: build Change-Id: I01d217468ea6008eb46cc3a225d47e1e0b90865a --- services/surfaceflinger/BufferLayer.cpp | 57 ++++++++++++++++++++------------- services/surfaceflinger/Layer.cpp | 31 +++++++++++------- services/surfaceflinger/Layer.h | 16 +++++++-- 3 files changed, 69 insertions(+), 35 deletions(-) (limited to 'services/surfaceflinger/BufferLayer.cpp') diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index 4e214d1b74..a33ef2cd94 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -249,7 +249,8 @@ void BufferLayer::onDraw(const RenderArea& renderArea, const Region& clip, } // Set things up for texturing. - mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight()); + mTexture.setDimensions(mActiveBuffer->getWidth(), + mActiveBuffer->getHeight()); mTexture.setFiltering(useFiltering); mTexture.setMatrix(textureMatrix); @@ -299,10 +300,12 @@ void BufferLayer::setTransformHint(uint32_t orientation) const { bool BufferLayer::onPreComposition(nsecs_t refreshStartTime) { if (mBufferLatched) { Mutex::Autolock lock(mFrameEventHistoryMutex); - mFrameEventHistory.addPreComposition(mCurrentFrameNumber, refreshStartTime); + mFrameEventHistory.addPreComposition(mCurrentFrameNumber, + refreshStartTime); } mRefreshPending = false; - return mQueuedFrames > 0 || mSidebandStreamChanged || mAutoRefresh; + return mQueuedFrames > 0 || mSidebandStreamChanged || + mAutoRefresh; } bool BufferLayer::onPostComposition(const std::shared_ptr& glDoneFence, const std::shared_ptr& presentFence, @@ -314,8 +317,8 @@ bool BufferLayer::onPostComposition(const std::shared_ptr& glDoneFenc // Update mFrameEventHistory. { Mutex::Autolock lock(mFrameEventHistoryMutex); - mFrameEventHistory.addPostComposition(mCurrentFrameNumber, glDoneFence, presentFence, - compositorTiming); + mFrameEventHistory.addPostComposition(mCurrentFrameNumber, glDoneFence, + presentFence, compositorTiming); } // Update mFrameTracker. @@ -429,11 +432,12 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime // buffer mode. bool queuedBuffer = false; LayerRejecter r(mDrawingState, getCurrentState(), recomputeVisibleRegions, - getProducerStickyTransform() != 0, mName.string(), mOverrideScalingMode, - mFreezeGeometryUpdates); + getProducerStickyTransform() != 0, mName.string(), + mOverrideScalingMode, mFreezeGeometryUpdates); status_t updateResult = - mSurfaceFlingerConsumer->updateTexImage(&r, mFlinger->mPrimaryDispSync, &mAutoRefresh, - &queuedBuffer, mLastFrameNumberReceived); + mSurfaceFlingerConsumer->updateTexImage(&r, mFlinger->mPrimaryDispSync, + &mAutoRefresh, &queuedBuffer, + mLastFrameNumberReceived); if (updateResult == BufferQueue::PRESENT_LATER) { // Producer doesn't want buffer to be displayed yet. Signal a // layer update so we check again at the next opportunity. @@ -486,12 +490,14 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime // Decrement the queued-frames count. Signal another event if we // have more frames pending. - if ((queuedBuffer && android_atomic_dec(&mQueuedFrames) > 1) || mAutoRefresh) { + if ((queuedBuffer && android_atomic_dec(&mQueuedFrames) > 1) || + mAutoRefresh) { mFlinger->signalLayerUpdate(); } // update the active buffer - mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer(&mActiveBufferSlot); + mActiveBuffer = + mSurfaceFlingerConsumer->getCurrentBuffer(&mActiveBufferSlot); if (mActiveBuffer == NULL) { // this can only happen if the very first buffer was rejected. return outDirtyRegion; @@ -519,7 +525,8 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime Rect crop(mSurfaceFlingerConsumer->getCurrentCrop()); const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform()); const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode()); - if ((crop != mCurrentCrop) || (transform != mCurrentTransform) || + if ((crop != mCurrentCrop) || + (transform != mCurrentTransform) || (scalingMode != mCurrentScalingMode)) { mCurrentCrop = crop; mCurrentTransform = transform; @@ -605,7 +612,8 @@ void BufferLayer::setPerFrameData(const sp& displayDevice) error = hwcLayer->setSidebandStream(mSidebandStream->handle()); if (error != HWC2::Error::None) { ALOGE("[%s] Failed to set sideband stream %p: %s (%d)", mName.string(), - mSidebandStream->handle(), to_string(error).c_str(), static_cast(error)); + mSidebandStream->handle(), to_string(error).c_str(), + static_cast(error)); } return; } @@ -628,13 +636,15 @@ void BufferLayer::setPerFrameData(const sp& displayDevice) uint32_t hwcSlot = 0; sp hwcBuffer; - hwcInfo.bufferCache.getHwcBuffer(mActiveBufferSlot, mActiveBuffer, &hwcSlot, &hwcBuffer); + hwcInfo.bufferCache.getHwcBuffer(mActiveBufferSlot, + mActiveBuffer, &hwcSlot, &hwcBuffer); auto acquireFence = mSurfaceFlingerConsumer->getCurrentFence(); error = hwcLayer->setBuffer(hwcSlot, hwcBuffer, acquireFence); if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(), mActiveBuffer->handle, - to_string(error).c_str(), static_cast(error)); + ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(), + mActiveBuffer->handle, to_string(error).c_str(), + static_cast(error)); } } @@ -688,7 +698,8 @@ void BufferLayer::onFrameAvailable(const BufferItem& item) { // Ensure that callbacks are handled in order while (item.mFrameNumber != mLastFrameNumberReceived + 1) { - status_t result = mQueueItemCondition.waitRelative(mQueueItemLock, ms2ns(500)); + status_t result = mQueueItemCondition.waitRelative(mQueueItemLock, + ms2ns(500)); if (result != NO_ERROR) { ALOGE("[%s] Timed out waiting on callback", mName.string()); } @@ -711,7 +722,8 @@ void BufferLayer::onFrameReplaced(const BufferItem& item) { // Ensure that callbacks are handled in order while (item.mFrameNumber != mLastFrameNumberReceived + 1) { - status_t result = mQueueItemCondition.waitRelative(mQueueItemLock, ms2ns(500)); + status_t result = mQueueItemCondition.waitRelative(mQueueItemLock, + ms2ns(500)); if (result != NO_ERROR) { ALOGE("[%s] Timed out waiting on callback", mName.string()); } @@ -765,7 +777,7 @@ bool BufferLayer::getOpacityForFormat(uint32_t format) { void BufferLayer::drawWithOpenGL(const RenderArea& renderArea, bool useIdentityTransform) const { const State& s(getDrawingState()); - computeGeometry(renderArea, mMesh, useIdentityTransform); + computeGeometry(renderArea, getBE().mMesh, useIdentityTransform); /* * NOTE: the way we compute the texture coordinates here produces @@ -802,7 +814,7 @@ void BufferLayer::drawWithOpenGL(const RenderArea& renderArea, bool useIdentityT // TODO: we probably want to generate the texture coords with the mesh // here we assume that we only have 4 vertices - Mesh::VertexArray texCoords(mMesh.getTexCoordArray()); + Mesh::VertexArray texCoords(getBE().mMesh.getTexCoordArray()); texCoords[0] = vec2(left, 1.0f - top); texCoords[1] = vec2(left, 1.0f - bottom); texCoords[2] = vec2(right, 1.0f - bottom); @@ -812,7 +824,7 @@ void BufferLayer::drawWithOpenGL(const RenderArea& renderArea, bool useIdentityT engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), false /* disableTexture */, getColor()); engine.setSourceDataSpace(mCurrentState.dataSpace); - engine.drawMesh(mMesh); + engine.drawMesh(getBE().mMesh); engine.disableBlending(); } @@ -866,7 +878,8 @@ bool BufferLayer::headFenceHasSignaled() const { // able to be latched. To avoid this, grab this buffer anyway. return true; } - return mQueueItems[0].mFenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING; + return mQueueItems[0].mFenceTime->getSignalTime() != + Fence::SIGNAL_TIME_PENDING; } uint32_t BufferLayer::getEffectiveScalingMode() const { diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 3be7f47b34..e29132dc8b 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -62,6 +62,11 @@ namespace android { +LayerBE::LayerBE() + : mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2) { +} + + int32_t Layer::sSequence = 1; Layer::Layer(SurfaceFlinger* flinger, const sp& client, const String8& name, uint32_t w, @@ -84,7 +89,6 @@ Layer::Layer(SurfaceFlinger* flinger, const sp& client, const String8& n mFrameLatencyNeeded(false), mFiltering(false), mNeedsFiltering(false), - mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2), mProtectedByApp(false), mClientRef(client), mPotentialCursor(false), @@ -133,6 +137,7 @@ Layer::Layer(SurfaceFlinger* flinger, const sp& client, const String8& n CompositorTiming compositorTiming; flinger->getCompositorTiming(&compositorTiming); mFrameEventHistory.initializeCompositorTiming(compositorTiming); + } void Layer::onFirstRef() {} @@ -204,7 +209,8 @@ sp Layer::getHandle() { // --------------------------------------------------------------------------- bool Layer::createHwcLayer(HWComposer* hwc, int32_t hwcId) { - LOG_ALWAYS_FATAL_IF(mHwcLayers.count(hwcId) != 0, "Already have a layer for hwcId %d", hwcId); + LOG_ALWAYS_FATAL_IF(mHwcLayers.count(hwcId) != 0, + "Already have a layer for hwcId %d", hwcId); HWC2::Layer* layer = hwc->createLayer(hwcId); if (!layer) { return false; @@ -634,7 +640,8 @@ bool Layer::getForceClientComposition(int32_t hwcId) { void Layer::updateCursorPosition(const sp& displayDevice) { auto hwcId = displayDevice->getHwcDisplayId(); - if (mHwcLayers.count(hwcId) == 0 || getCompositionType(hwcId) != HWC2::Composition::Cursor) { + if (mHwcLayers.count(hwcId) == 0 || + getCompositionType(hwcId) != HWC2::Composition::Cursor) { return; } @@ -657,7 +664,8 @@ void Layer::updateCursorPosition(const sp& displayDevice) { auto& displayTransform(displayDevice->getTransform()); auto position = displayTransform.transform(frame); - auto error = mHwcLayers[hwcId].layer->setCursorPosition(position.left, position.top); + auto error = mHwcLayers[hwcId].layer->setCursorPosition(position.left, + position.top); ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set cursor position " "to (%d, %d): %s (%d)", @@ -684,9 +692,9 @@ void Layer::draw(const RenderArea& renderArea) const { void Layer::clearWithOpenGL(const RenderArea& renderArea, float red, float green, float blue, float alpha) const { RenderEngine& engine(mFlinger->getRenderEngine()); - computeGeometry(renderArea, mMesh, false); + computeGeometry(renderArea, getBE().mMesh, false); engine.setupFillWithColor(red, green, blue, alpha); - engine.drawMesh(mMesh); + engine.drawMesh(getBE().mMesh); } void Layer::clearWithOpenGL(const RenderArea& renderArea) const { @@ -961,11 +969,12 @@ uint32_t Layer::doTransaction(uint32_t flags) { " requested={ wh={%4u,%4u} }}\n" " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" " requested={ wh={%4u,%4u} }}\n", - this, getName().string(), mCurrentTransform, getEffectiveScalingMode(), c.active.w, - c.active.h, c.crop.left, c.crop.top, c.crop.right, c.crop.bottom, - c.crop.getWidth(), c.crop.getHeight(), c.requested.w, c.requested.h, s.active.w, - s.active.h, s.crop.left, s.crop.top, s.crop.right, s.crop.bottom, - s.crop.getWidth(), s.crop.getHeight(), s.requested.w, s.requested.h); + this, getName().string(), mCurrentTransform, + getEffectiveScalingMode(), c.active.w, c.active.h, c.crop.left, c.crop.top, + c.crop.right, c.crop.bottom, c.crop.getWidth(), c.crop.getHeight(), c.requested.w, + c.requested.h, s.active.w, s.active.h, s.crop.left, s.crop.top, s.crop.right, + s.crop.bottom, s.crop.getWidth(), s.crop.getHeight(), s.requested.w, + s.requested.h); // record the new size, form this point on, when the client request // a buffer, it'll get the new size. diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 9ea800e197..5dfc963c8b 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -65,13 +65,25 @@ class DisplayDevice; class GraphicBuffer; class SurfaceFlinger; class LayerDebugInfo; +class LayerBE; // --------------------------------------------------------------------------- +class LayerBE { +public: + LayerBE(); + + // The mesh used to draw the layer in GLES composition mode + Mesh mMesh; + +}; + class Layer : public virtual RefBase { static int32_t sSequence; public: + LayerBE& getBE() { return mBE; } + LayerBE& getBE() const { return mBE; } mutable bool contentDirty; // regions below are in window-manager space Region visibleRegion; @@ -652,8 +664,6 @@ protected: bool mFiltering; // Whether filtering is needed b/c of the drawingstate bool mNeedsFiltering; - // The mesh used to draw the layer in GLES composition mode - mutable Mesh mMesh; bool mPendingRemoval = false; @@ -708,6 +718,8 @@ protected: wp mCurrentParent; wp mDrawingParent; + + mutable LayerBE mBE; }; // --------------------------------------------------------------------------- -- cgit v1.2.3-59-g8ed1b From 386c22e70d63ecc8bf6ae3e7c2f623f42fcd8718 Mon Sep 17 00:00:00 2001 From: David Sodman Date: Thu, 9 Nov 2017 16:34:46 -0800 Subject: SF: replicate mSidebandStream in LayerBE Add a copy of mSidebandStream in LayerBE. This is one of the few data items that is replicated in both FE and BE. Test: build Change-Id: Ief98645a4fa178e2606c0c337b3f260a1766597a --- services/surfaceflinger/BufferLayer.cpp | 14 ++++++++------ services/surfaceflinger/Layer.cpp | 2 +- services/surfaceflinger/Layer.h | 2 ++ 3 files changed, 11 insertions(+), 7 deletions(-) (limited to 'services/surfaceflinger/BufferLayer.cpp') diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index a33ef2cd94..f37f0abaca 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -115,7 +115,7 @@ bool BufferLayer::isProtected() const { bool BufferLayer::isVisible() const { return !(isHiddenByPolicy()) && getAlpha() > 0.0f && - (mActiveBuffer != NULL || mSidebandStream != NULL); + (mActiveBuffer != NULL || getBE().mSidebandStream != NULL); } bool BufferLayer::isFixedSize() const { @@ -385,7 +385,9 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) { // mSidebandStreamChanged was true mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream(); - if (mSidebandStream != NULL) { + // replicated in LayerBE until FE/BE is ready to be synchronized + getBE().mSidebandStream = mSidebandStream; + if (getBE().mSidebandStream != NULL) { setTransactionFlags(eTransactionNeeded); mFlinger->setTransactionFlags(eTraversalNeeded); } @@ -606,13 +608,13 @@ void BufferLayer::setPerFrameData(const sp& displayDevice) } // Sideband layers - if (mSidebandStream.get()) { + if (getBE().mSidebandStream.get()) { setCompositionType(hwcId, HWC2::Composition::Sideband); ALOGV("[%s] Requesting Sideband composition", mName.string()); - error = hwcLayer->setSidebandStream(mSidebandStream->handle()); + error = hwcLayer->setSidebandStream(getBE().mSidebandStream->handle()); if (error != HWC2::Error::None) { ALOGE("[%s] Failed to set sideband stream %p: %s (%d)", mName.string(), - mSidebandStream->handle(), to_string(error).c_str(), + getBE().mSidebandStream->handle(), to_string(error).c_str(), static_cast(error)); } return; @@ -651,7 +653,7 @@ void BufferLayer::setPerFrameData(const sp& displayDevice) bool BufferLayer::isOpaque(const Layer::State& s) const { // if we don't have a buffer or sidebandStream yet, we're translucent regardless of the // layer's opaque flag. - if ((mSidebandStream == nullptr) && (mActiveBuffer == nullptr)) { + if ((getBE().mSidebandStream == nullptr) && (mActiveBuffer == nullptr)) { return false; } diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index e29132dc8b..f4eace8641 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -1002,7 +1002,7 @@ uint32_t Layer::doTransaction(uint32_t flags) { const bool resizePending = ((c.requested.w != c.active.w) || (c.requested.h != c.active.h)) && (mActiveBuffer != nullptr); if (!isFixedSize()) { - if (resizePending && mSidebandStream == NULL) { + if (resizePending && getBE().mSidebandStream == NULL) { flags |= eDontUpdateGeometryState; } } diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 5dfc963c8b..b5638e0072 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -73,6 +73,8 @@ class LayerBE { public: LayerBE(); + sp mSidebandStream; + // The mesh used to draw the layer in GLES composition mode Mesh mMesh; -- cgit v1.2.3-59-g8ed1b From 6f65f3e7caab86a76419e7c1d1c787634a0852d8 Mon Sep 17 00:00:00 2001 From: David Sodman Date: Fri, 3 Nov 2017 14:28:09 -0700 Subject: SF: mHwcLayers to LayerBE Move mHwcLayers to LayerBE Test: build Change-Id: I16918223d02ae8017656fa1385ed58bbb21aa688 --- services/surfaceflinger/BufferLayer.cpp | 4 +-- services/surfaceflinger/ColorLayer.cpp | 2 +- services/surfaceflinger/Layer.cpp | 56 ++++++++++++++++---------------- services/surfaceflinger/Layer.h | 57 +++++++++++++++++---------------- 4 files changed, 60 insertions(+), 59 deletions(-) (limited to 'services/surfaceflinger/BufferLayer.cpp') diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index f37f0abaca..2fa17e9d44 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -88,7 +88,7 @@ BufferLayer::~BufferLayer() { } mFlinger->deleteTextureAsync(mTextureName); - if (!mHwcLayers.empty()) { + if (!getBE().mHwcLayers.empty()) { ALOGE("Found stale hardware composer layers when destroying " "surface flinger layer %s", mName.string()); @@ -591,7 +591,7 @@ void BufferLayer::setPerFrameData(const sp& displayDevice) const auto& viewport = displayDevice->getViewport(); Region visible = tr.transform(visibleRegion.intersect(viewport)); auto hwcId = displayDevice->getHwcDisplayId(); - auto& hwcInfo = mHwcLayers[hwcId]; + auto& hwcInfo = getBE().mHwcLayers[hwcId]; auto& hwcLayer = hwcInfo.layer; auto error = hwcLayer->setVisibleRegion(visible); if (error != HWC2::Error::None) { diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp index 292e1a7350..b784c8d956 100644 --- a/services/surfaceflinger/ColorLayer.cpp +++ b/services/surfaceflinger/ColorLayer.cpp @@ -66,7 +66,7 @@ void ColorLayer::setPerFrameData(const sp& displayDevice) { const auto& viewport = displayDevice->getViewport(); Region visible = tr.transform(visibleRegion.intersect(viewport)); auto hwcId = displayDevice->getHwcDisplayId(); - auto& hwcInfo = mHwcLayers[hwcId]; + auto& hwcInfo = getBE().mHwcLayers[hwcId]; auto& hwcLayer = hwcInfo.layer; auto error = hwcLayer->setVisibleRegion(visible); diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index f4eace8641..359b64fe72 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -209,42 +209,42 @@ sp Layer::getHandle() { // --------------------------------------------------------------------------- bool Layer::createHwcLayer(HWComposer* hwc, int32_t hwcId) { - LOG_ALWAYS_FATAL_IF(mHwcLayers.count(hwcId) != 0, + LOG_ALWAYS_FATAL_IF(getBE().mHwcLayers.count(hwcId) != 0, "Already have a layer for hwcId %d", hwcId); HWC2::Layer* layer = hwc->createLayer(hwcId); if (!layer) { return false; } - HWCInfo& hwcInfo = mHwcLayers[hwcId]; + LayerBE::HWCInfo& hwcInfo = getBE().mHwcLayers[hwcId]; hwcInfo.hwc = hwc; hwcInfo.layer = layer; layer->setLayerDestroyedListener( - [this, hwcId](HWC2::Layer* /*layer*/) { mHwcLayers.erase(hwcId); }); + [this, hwcId](HWC2::Layer* /*layer*/) { getBE().mHwcLayers.erase(hwcId); }); return true; } bool Layer::destroyHwcLayer(int32_t hwcId) { - if (mHwcLayers.count(hwcId) == 0) { + if (getBE().mHwcLayers.count(hwcId) == 0) { return false; } - auto& hwcInfo = mHwcLayers[hwcId]; + auto& hwcInfo = getBE().mHwcLayers[hwcId]; LOG_ALWAYS_FATAL_IF(hwcInfo.layer == nullptr, "Attempt to destroy null layer"); LOG_ALWAYS_FATAL_IF(hwcInfo.hwc == nullptr, "Missing HWComposer"); hwcInfo.hwc->destroyLayer(hwcId, hwcInfo.layer); // The layer destroyed listener should have cleared the entry from // mHwcLayers. Verify that. - LOG_ALWAYS_FATAL_IF(mHwcLayers.count(hwcId) != 0, "Stale layer entry in mHwcLayers"); - + LOG_ALWAYS_FATAL_IF(getBE().mHwcLayers.count(hwcId) != 0, + "Stale layer entry in getBE().mHwcLayers"); return true; } void Layer::destroyAllHwcLayers() { - size_t numLayers = mHwcLayers.size(); + size_t numLayers = getBE().mHwcLayers.size(); for (size_t i = 0; i < numLayers; ++i) { - LOG_ALWAYS_FATAL_IF(mHwcLayers.empty(), "destroyAllHwcLayers failed"); - destroyHwcLayer(mHwcLayers.begin()->first); + LOG_ALWAYS_FATAL_IF(getBE().mHwcLayers.empty(), "destroyAllHwcLayers failed"); + destroyHwcLayer(getBE().mHwcLayers.begin()->first); } - LOG_ALWAYS_FATAL_IF(!mHwcLayers.empty(), + LOG_ALWAYS_FATAL_IF(!getBE().mHwcLayers.empty(), "All hardware composer layers should have been destroyed"); } @@ -465,7 +465,7 @@ FloatRect Layer::computeCrop(const sp& hw) const { void Layer::setGeometry(const sp& displayDevice, uint32_t z) { const auto hwcId = displayDevice->getHwcDisplayId(); - auto& hwcInfo = mHwcLayers[hwcId]; + auto& hwcInfo = getBE().mHwcLayers[hwcId]; // enable this layer hwcInfo.forceClientComposition = false; @@ -621,26 +621,26 @@ void Layer::setGeometry(const sp& displayDevice, uint32_t z } void Layer::forceClientComposition(int32_t hwcId) { - if (mHwcLayers.count(hwcId) == 0) { + if (getBE().mHwcLayers.count(hwcId) == 0) { ALOGE("forceClientComposition: no HWC layer found (%d)", hwcId); return; } - mHwcLayers[hwcId].forceClientComposition = true; + getBE().mHwcLayers[hwcId].forceClientComposition = true; } bool Layer::getForceClientComposition(int32_t hwcId) { - if (mHwcLayers.count(hwcId) == 0) { + if (getBE().mHwcLayers.count(hwcId) == 0) { ALOGE("getForceClientComposition: no HWC layer found (%d)", hwcId); return false; } - return mHwcLayers[hwcId].forceClientComposition; + return getBE().mHwcLayers[hwcId].forceClientComposition; } void Layer::updateCursorPosition(const sp& displayDevice) { auto hwcId = displayDevice->getHwcDisplayId(); - if (mHwcLayers.count(hwcId) == 0 || + if (getBE().mHwcLayers.count(hwcId) == 0 || getCompositionType(hwcId) != HWC2::Composition::Cursor) { return; } @@ -664,7 +664,7 @@ void Layer::updateCursorPosition(const sp& displayDevice) { auto& displayTransform(displayDevice->getTransform()); auto position = displayTransform.transform(frame); - auto error = mHwcLayers[hwcId].layer->setCursorPosition(position.left, + auto error = getBE().mHwcLayers[hwcId].layer->setCursorPosition(position.left, position.top); ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set cursor position " @@ -702,11 +702,11 @@ void Layer::clearWithOpenGL(const RenderArea& renderArea) const { } void Layer::setCompositionType(int32_t hwcId, HWC2::Composition type, bool callIntoHwc) { - if (mHwcLayers.count(hwcId) == 0) { + if (getBE().mHwcLayers.count(hwcId) == 0) { ALOGE("setCompositionType called without a valid HWC layer"); return; } - auto& hwcInfo = mHwcLayers[hwcId]; + auto& hwcInfo = getBE().mHwcLayers[hwcId]; auto& hwcLayer = hwcInfo.layer; ALOGV("setCompositionType(%" PRIx64 ", %s, %d)", hwcLayer->getId(), to_string(type).c_str(), static_cast(callIntoHwc)); @@ -730,27 +730,27 @@ HWC2::Composition Layer::getCompositionType(int32_t hwcId) const { // have a HWC counterpart, then it will always be Client return HWC2::Composition::Client; } - if (mHwcLayers.count(hwcId) == 0) { + if (getBE().mHwcLayers.count(hwcId) == 0) { ALOGE("getCompositionType called with an invalid HWC layer"); return HWC2::Composition::Invalid; } - return mHwcLayers.at(hwcId).compositionType; + return getBE().mHwcLayers.at(hwcId).compositionType; } void Layer::setClearClientTarget(int32_t hwcId, bool clear) { - if (mHwcLayers.count(hwcId) == 0) { + if (getBE().mHwcLayers.count(hwcId) == 0) { ALOGE("setClearClientTarget called without a valid HWC layer"); return; } - mHwcLayers[hwcId].clearClientTarget = clear; + getBE().mHwcLayers[hwcId].clearClientTarget = clear; } bool Layer::getClearClientTarget(int32_t hwcId) const { - if (mHwcLayers.count(hwcId) == 0) { + if (getBE().mHwcLayers.count(hwcId) == 0) { ALOGE("getClearClientTarget called without a valid HWC layer"); return false; } - return mHwcLayers.at(hwcId).clearClientTarget; + return getBE().mHwcLayers.at(hwcId).clearClientTarget; } bool Layer::addSyncPoint(const std::shared_ptr& point) { @@ -1432,7 +1432,7 @@ void Layer::miniDumpHeader(String8& result) { } void Layer::miniDump(String8& result, int32_t hwcId) const { - if (mHwcLayers.count(hwcId) == 0) { + if (getBE().mHwcLayers.count(hwcId) == 0) { return; } @@ -1450,7 +1450,7 @@ void Layer::miniDump(String8& result, int32_t hwcId) const { result.appendFormat(" %s\n", name.string()); const Layer::State& layerState(getDrawingState()); - const HWCInfo& hwcInfo = mHwcLayers.at(hwcId); + const LayerBE::HWCInfo& hwcInfo = getBE().mHwcLayers.at(hwcId); result.appendFormat(" %10d | ", layerState.z); result.appendFormat("%10s | ", to_string(getCompositionType(hwcId)).c_str()); const Rect& frame = hwcInfo.displayFrame; diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index b5638e0072..b7b7a3a828 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -78,6 +78,30 @@ public: // The mesh used to draw the layer in GLES composition mode Mesh mMesh; + // HWC items, accessed from the main thread + struct HWCInfo { + HWCInfo() + : hwc(nullptr), + layer(nullptr), + forceClientComposition(false), + compositionType(HWC2::Composition::Invalid), + clearClientTarget(false) {} + + HWComposer* hwc; + HWC2::Layer* layer; + bool forceClientComposition; + HWC2::Composition compositionType; + bool clearClientTarget; + Rect displayFrame; + FloatRect sourceCrop; + HWComposerBufferCache bufferCache; + }; + + // A layer can be attached to multiple displays when operating in mirror mode + // (a.k.a: when several displays are attached with equal layerStack). In this + // case we need to keep track. In non-mirror mode, a layer will have only one + // HWCInfo. This map key is a display layerStack. + std::unordered_map mHwcLayers; }; class Layer : public virtual RefBase { @@ -431,13 +455,15 @@ public: bool destroyHwcLayer(int32_t hwcId); void destroyAllHwcLayers(); - bool hasHwcLayer(int32_t hwcId) { return mHwcLayers.count(hwcId) > 0; } + bool hasHwcLayer(int32_t hwcId) { + return getBE().mHwcLayers.count(hwcId) > 0; + } HWC2::Layer* getHwcLayer(int32_t hwcId) { - if (mHwcLayers.count(hwcId) == 0) { + if (getBE().mHwcLayers.count(hwcId) == 0) { return nullptr; } - return mHwcLayers[hwcId].layer; + return getBE().mHwcLayers[hwcId].layer; } // ----------------------------------------------------------------------- @@ -669,31 +695,6 @@ protected: bool mPendingRemoval = false; - // HWC items, accessed from the main thread - struct HWCInfo { - HWCInfo() - : hwc(nullptr), - layer(nullptr), - forceClientComposition(false), - compositionType(HWC2::Composition::Invalid), - clearClientTarget(false) {} - - HWComposer* hwc; - HWC2::Layer* layer; - bool forceClientComposition; - HWC2::Composition compositionType; - bool clearClientTarget; - Rect displayFrame; - FloatRect sourceCrop; - HWComposerBufferCache bufferCache; - }; - - // A layer can be attached to multiple displays when operating in mirror mode - // (a.k.a: when several displays are attached with equal layerStack). In this - // case we need to keep track. In non-mirror mode, a layer will have only one - // HWCInfo. This map key is a display layerStack. - std::unordered_map mHwcLayers; - // page-flip thread (currently main thread) bool mProtectedByApp; // application requires protected path to external sink -- cgit v1.2.3-59-g8ed1b From 5b4cffc352f7f5d3711d4b7798a07434a998b2d7 Mon Sep 17 00:00:00 2001 From: David Sodman Date: Thu, 23 Nov 2017 13:20:29 -0800 Subject: SF: replicate mActiveBuffer in LayerBE as mBuffer Replicate mAcitveBuffer in LayerBE as mBuffer Test: build/run Change-Id: Iaec4eeddbf4ca1798a47ecbb6c0b6c82ceb1d27c --- services/surfaceflinger/BufferLayer.cpp | 45 ++++++++++++++++++--------------- services/surfaceflinger/Layer.cpp | 38 +++++++++++++++------------- services/surfaceflinger/Layer.h | 5 ++-- 3 files changed, 47 insertions(+), 41 deletions(-) (limited to 'services/surfaceflinger/BufferLayer.cpp') diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index 2fa17e9d44..0d947b1fe0 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -109,13 +109,14 @@ void BufferLayer::useEmptyDamage() { } bool BufferLayer::isProtected() const { - const sp& activeBuffer(mActiveBuffer); - return (activeBuffer != 0) && (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED); + const sp& buffer(getBE().mBuffer); + return (buffer != 0) && + (buffer->getUsage() & GRALLOC_USAGE_PROTECTED); } bool BufferLayer::isVisible() const { return !(isHiddenByPolicy()) && getAlpha() > 0.0f && - (mActiveBuffer != NULL || getBE().mSidebandStream != NULL); + (getBE().mBuffer != NULL || getBE().mSidebandStream != NULL); } bool BufferLayer::isFixedSize() const { @@ -171,7 +172,7 @@ void BufferLayer::onDraw(const RenderArea& renderArea, const Region& clip, bool useIdentityTransform) const { ATRACE_CALL(); - if (CC_UNLIKELY(mActiveBuffer == 0)) { + if (CC_UNLIKELY(getBE().mBuffer == 0)) { // the texture has not been created yet, this Layer has // in fact never been drawn into. This happens frequently with // SurfaceView because the WindowManager can't know when the client @@ -249,8 +250,8 @@ void BufferLayer::onDraw(const RenderArea& renderArea, const Region& clip, } // Set things up for texturing. - mTexture.setDimensions(mActiveBuffer->getWidth(), - mActiveBuffer->getHeight()); + mTexture.setDimensions(getBE().mBuffer->getWidth(), + getBE().mBuffer->getHeight()); mTexture.setFiltering(useFiltering); mTexture.setMatrix(textureMatrix); @@ -421,7 +422,7 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime // Capture the old state of the layer for comparisons later const State& s(getDrawingState()); const bool oldOpacity = isOpaque(s); - sp oldActiveBuffer = mActiveBuffer; + sp oldBuffer = getBE().mBuffer; if (!allTransactionsSignaled()) { mFlinger->signalLayerUpdate(); @@ -498,9 +499,11 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime } // update the active buffer - mActiveBuffer = - mSurfaceFlingerConsumer->getCurrentBuffer(&mActiveBufferSlot); - if (mActiveBuffer == NULL) { + getBE().mBuffer = + mSurfaceFlingerConsumer->getCurrentBuffer(&getBE().mBufferSlot); + // replicated in LayerBE until FE/BE is ready to be synchronized + mActiveBuffer = getBE().mBuffer; + if (getBE().mBuffer == NULL) { // this can only happen if the very first buffer was rejected. return outDirtyRegion; } @@ -516,7 +519,7 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime mRefreshPending = true; mFrameLatencyNeeded = true; - if (oldActiveBuffer == NULL) { + if (oldBuffer == NULL) { // the first time we receive a buffer, we need to trigger a // geometry invalidation. recomputeVisibleRegions = true; @@ -536,16 +539,16 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime recomputeVisibleRegions = true; } - if (oldActiveBuffer != NULL) { - uint32_t bufWidth = mActiveBuffer->getWidth(); - uint32_t bufHeight = mActiveBuffer->getHeight(); - if (bufWidth != uint32_t(oldActiveBuffer->width) || - bufHeight != uint32_t(oldActiveBuffer->height)) { + if (oldBuffer != NULL) { + uint32_t bufWidth = getBE().mBuffer->getWidth(); + uint32_t bufHeight = getBE().mBuffer->getHeight(); + if (bufWidth != uint32_t(oldBuffer->width) || + bufHeight != uint32_t(oldBuffer->height)) { recomputeVisibleRegions = true; } } - mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format); + mCurrentOpacity = getOpacityForFormat(getBE().mBuffer->format); if (oldOpacity != isOpaque(s)) { recomputeVisibleRegions = true; } @@ -638,14 +641,14 @@ void BufferLayer::setPerFrameData(const sp& displayDevice) uint32_t hwcSlot = 0; sp hwcBuffer; - hwcInfo.bufferCache.getHwcBuffer(mActiveBufferSlot, - mActiveBuffer, &hwcSlot, &hwcBuffer); + hwcInfo.bufferCache.getHwcBuffer(getBE().mBufferSlot, + getBE().mBuffer, &hwcSlot, &hwcBuffer); auto acquireFence = mSurfaceFlingerConsumer->getCurrentFence(); error = hwcLayer->setBuffer(hwcSlot, hwcBuffer, acquireFence); if (error != HWC2::Error::None) { ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(), - mActiveBuffer->handle, to_string(error).c_str(), + getBE().mBuffer->handle, to_string(error).c_str(), static_cast(error)); } } @@ -653,7 +656,7 @@ void BufferLayer::setPerFrameData(const sp& displayDevice) bool BufferLayer::isOpaque(const Layer::State& s) const { // if we don't have a buffer or sidebandStream yet, we're translucent regardless of the // layer's opaque flag. - if ((getBE().mSidebandStream == nullptr) && (mActiveBuffer == nullptr)) { + if ((getBE().mSidebandStream == nullptr) && (getBE().mBuffer == nullptr)) { return false; } diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 359b64fe72..2a4abcb0a2 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -63,7 +63,9 @@ namespace android { LayerBE::LayerBE() - : mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2) { + : mBufferSlot(BufferQueue::INVALID_BUFFER_SLOT), + mBuffer(nullptr), + mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2) { } @@ -255,9 +257,9 @@ Rect Layer::getContentCrop() const { if (!mCurrentCrop.isEmpty()) { // if the buffer crop is defined, we use that crop = mCurrentCrop; - } else if (mActiveBuffer != NULL) { + } else if (getBE().mBuffer != NULL) { // otherwise we use the whole buffer - crop = mActiveBuffer->getBounds(); + crop = getBE().mBuffer->getBounds(); } else { // if we don't have a buffer yet, we use an empty/invalid crop crop.makeInvalid(); @@ -1000,7 +1002,7 @@ uint32_t Layer::doTransaction(uint32_t flags) { // to the old buffer. However in the state where we don't have an old buffer // there is no such concern but we may still be being used as a parent layer. const bool resizePending = ((c.requested.w != c.active.w) || (c.requested.h != c.active.h)) && - (mActiveBuffer != nullptr); + (getBE().mBuffer != nullptr); if (!isFixedSize()) { if (resizePending && getBE().mSidebandStream == NULL) { flags |= eDontUpdateGeometryState; @@ -1399,12 +1401,12 @@ LayerDebugInfo Layer::getLayerDebugInfo() const { info.mMatrix[1][0] = ds.active.transform[1][0]; info.mMatrix[1][1] = ds.active.transform[1][1]; { - sp activeBuffer = getActiveBuffer(); - if (activeBuffer != 0) { - info.mActiveBufferWidth = activeBuffer->getWidth(); - info.mActiveBufferHeight = activeBuffer->getHeight(); - info.mActiveBufferStride = activeBuffer->getStride(); - info.mActiveBufferFormat = activeBuffer->format; + sp buffer = getBE().mBuffer; + if (buffer != 0) { + info.mActiveBufferWidth = buffer->getWidth(); + info.mActiveBufferHeight = buffer->getHeight(); + info.mActiveBufferStride = buffer->getStride(); + info.mActiveBufferFormat = buffer->format; } else { info.mActiveBufferWidth = 0; info.mActiveBufferHeight = 0; @@ -1718,15 +1720,15 @@ Transform Layer::getTransform() const { // for in the transform. We need to mirror this scaling in child surfaces // or we will break the contract where WM can treat child surfaces as // pixels in the parent surface. - if (p->isFixedSize() && p->mActiveBuffer != nullptr) { + if (p->isFixedSize() && p->getBE().mBuffer != nullptr) { int bufferWidth; int bufferHeight; if ((p->mCurrentTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) == 0) { - bufferWidth = p->mActiveBuffer->getWidth(); - bufferHeight = p->mActiveBuffer->getHeight(); + bufferWidth = p->getBE().mBuffer->getWidth(); + bufferHeight = p->getBE().mBuffer->getHeight(); } else { - bufferHeight = p->mActiveBuffer->getWidth(); - bufferWidth = p->mActiveBuffer->getHeight(); + bufferHeight = p->getBE().mBuffer->getWidth(); + bufferWidth = p->getBE().mBuffer->getHeight(); } float sx = p->getDrawingState().active.w / static_cast(bufferWidth); float sy = p->getDrawingState().active.h / static_cast(bufferHeight); @@ -1826,9 +1828,9 @@ void Layer::writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet) layerInfo->set_z_order_relative_of(zOrderRelativeOf->sequence); } - auto activeBuffer = getActiveBuffer(); - if (activeBuffer != nullptr) { - LayerProtoHelper::writeToProto(activeBuffer, layerInfo->mutable_active_buffer()); + auto buffer = getBE().mBuffer; + if (buffer != nullptr) { + LayerProtoHelper::writeToProto(buffer, layerInfo->mutable_active_buffer()); } layerInfo->set_queued_frames(getQueuedFrameCount()); diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index b12e34fd11..8ac50943b1 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -70,6 +70,9 @@ class LayerBE { public: LayerBE(); + // main thread + int mBufferSlot; + sp mBuffer; sp mSidebandStream; // The mesh used to draw the layer in GLES composition mode @@ -469,8 +472,6 @@ public: void setFiltering(bool filtering); bool getFiltering() const; - // only for debugging - inline const sp& getActiveBuffer() const { return mActiveBuffer; } inline const State& getDrawingState() const { return mDrawingState; } inline const State& getCurrentState() const { return mCurrentState; } -- cgit v1.2.3-59-g8ed1b From 0cc69188196037c06127c0bc56c516069dbaa558 Mon Sep 17 00:00:00 2001 From: David Sodman Date: Fri, 17 Nov 2017 12:12:07 -0800 Subject: SF: Add CompositionInfo to LayerBE Add CompositionInfo structure to LayerBE that tracks the actual data that will be used by SurfaceFlinger to compose a frame Test: Build and run manually Change-Id: I2523de430bb14f9d8f149ba011b25a7a470eae2d --- services/surfaceflinger/BufferLayer.cpp | 44 ++++++++++++++++----------------- services/surfaceflinger/Layer.cpp | 27 +++++++++----------- services/surfaceflinger/Layer.h | 36 +++++++++++++++++++++++---- 3 files changed, 65 insertions(+), 42 deletions(-) (limited to 'services/surfaceflinger/BufferLayer.cpp') diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index 0d947b1fe0..e8f4150135 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -109,14 +109,14 @@ void BufferLayer::useEmptyDamage() { } bool BufferLayer::isProtected() const { - const sp& buffer(getBE().mBuffer); + const sp& buffer(getBE().compositionInfo.mBuffer); return (buffer != 0) && (buffer->getUsage() & GRALLOC_USAGE_PROTECTED); } bool BufferLayer::isVisible() const { return !(isHiddenByPolicy()) && getAlpha() > 0.0f && - (getBE().mBuffer != NULL || getBE().mSidebandStream != NULL); + (getBE().compositionInfo.mBuffer != NULL || getBE().compositionInfo.hwc.sidebandStream != NULL); } bool BufferLayer::isFixedSize() const { @@ -172,7 +172,7 @@ void BufferLayer::onDraw(const RenderArea& renderArea, const Region& clip, bool useIdentityTransform) const { ATRACE_CALL(); - if (CC_UNLIKELY(getBE().mBuffer == 0)) { + if (CC_UNLIKELY(getBE().compositionInfo.mBuffer == 0)) { // the texture has not been created yet, this Layer has // in fact never been drawn into. This happens frequently with // SurfaceView because the WindowManager can't know when the client @@ -250,8 +250,8 @@ void BufferLayer::onDraw(const RenderArea& renderArea, const Region& clip, } // Set things up for texturing. - mTexture.setDimensions(getBE().mBuffer->getWidth(), - getBE().mBuffer->getHeight()); + mTexture.setDimensions(getBE().compositionInfo.mBuffer->getWidth(), + getBE().compositionInfo.mBuffer->getHeight()); mTexture.setFiltering(useFiltering); mTexture.setMatrix(textureMatrix); @@ -387,8 +387,8 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime // mSidebandStreamChanged was true mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream(); // replicated in LayerBE until FE/BE is ready to be synchronized - getBE().mSidebandStream = mSidebandStream; - if (getBE().mSidebandStream != NULL) { + getBE().compositionInfo.hwc.sidebandStream = mSidebandStream; + if (getBE().compositionInfo.hwc.sidebandStream != NULL) { setTransactionFlags(eTransactionNeeded); mFlinger->setTransactionFlags(eTraversalNeeded); } @@ -422,7 +422,7 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime // Capture the old state of the layer for comparisons later const State& s(getDrawingState()); const bool oldOpacity = isOpaque(s); - sp oldBuffer = getBE().mBuffer; + sp oldBuffer = getBE().compositionInfo.mBuffer; if (!allTransactionsSignaled()) { mFlinger->signalLayerUpdate(); @@ -499,11 +499,11 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime } // update the active buffer - getBE().mBuffer = - mSurfaceFlingerConsumer->getCurrentBuffer(&getBE().mBufferSlot); + getBE().compositionInfo.mBuffer = + mSurfaceFlingerConsumer->getCurrentBuffer(&getBE().compositionInfo.mBufferSlot); // replicated in LayerBE until FE/BE is ready to be synchronized - mActiveBuffer = getBE().mBuffer; - if (getBE().mBuffer == NULL) { + mActiveBuffer = getBE().compositionInfo.mBuffer; + if (getBE().compositionInfo.mBuffer == NULL) { // this can only happen if the very first buffer was rejected. return outDirtyRegion; } @@ -540,15 +540,15 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime } if (oldBuffer != NULL) { - uint32_t bufWidth = getBE().mBuffer->getWidth(); - uint32_t bufHeight = getBE().mBuffer->getHeight(); + uint32_t bufWidth = getBE().compositionInfo.mBuffer->getWidth(); + uint32_t bufHeight = getBE().compositionInfo.mBuffer->getHeight(); if (bufWidth != uint32_t(oldBuffer->width) || bufHeight != uint32_t(oldBuffer->height)) { recomputeVisibleRegions = true; } } - mCurrentOpacity = getOpacityForFormat(getBE().mBuffer->format); + mCurrentOpacity = getOpacityForFormat(getBE().compositionInfo.mBuffer->format); if (oldOpacity != isOpaque(s)) { recomputeVisibleRegions = true; } @@ -611,13 +611,13 @@ void BufferLayer::setPerFrameData(const sp& displayDevice) } // Sideband layers - if (getBE().mSidebandStream.get()) { + if (getBE().compositionInfo.hwc.sidebandStream.get()) { setCompositionType(hwcId, HWC2::Composition::Sideband); ALOGV("[%s] Requesting Sideband composition", mName.string()); - error = hwcLayer->setSidebandStream(getBE().mSidebandStream->handle()); + error = hwcLayer->setSidebandStream(getBE().compositionInfo.hwc.sidebandStream->handle()); if (error != HWC2::Error::None) { ALOGE("[%s] Failed to set sideband stream %p: %s (%d)", mName.string(), - getBE().mSidebandStream->handle(), to_string(error).c_str(), + getBE().compositionInfo.hwc.sidebandStream->handle(), to_string(error).c_str(), static_cast(error)); } return; @@ -641,14 +641,14 @@ void BufferLayer::setPerFrameData(const sp& displayDevice) uint32_t hwcSlot = 0; sp hwcBuffer; - hwcInfo.bufferCache.getHwcBuffer(getBE().mBufferSlot, - getBE().mBuffer, &hwcSlot, &hwcBuffer); + hwcInfo.bufferCache.getHwcBuffer(getBE().compositionInfo.mBufferSlot, + getBE().compositionInfo.mBuffer, &hwcSlot, &hwcBuffer); auto acquireFence = mSurfaceFlingerConsumer->getCurrentFence(); error = hwcLayer->setBuffer(hwcSlot, hwcBuffer, acquireFence); if (error != HWC2::Error::None) { ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(), - getBE().mBuffer->handle, to_string(error).c_str(), + getBE().compositionInfo.mBuffer->handle, to_string(error).c_str(), static_cast(error)); } } @@ -656,7 +656,7 @@ void BufferLayer::setPerFrameData(const sp& displayDevice) bool BufferLayer::isOpaque(const Layer::State& s) const { // if we don't have a buffer or sidebandStream yet, we're translucent regardless of the // layer's opaque flag. - if ((getBE().mSidebandStream == nullptr) && (getBE().mBuffer == nullptr)) { + if ((getBE().compositionInfo.hwc.sidebandStream == nullptr) && (getBE().compositionInfo.mBuffer == nullptr)) { return false; } diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 298f597f34..fa4d289249 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -39,7 +39,6 @@ #include #include -#include #include #include @@ -63,9 +62,7 @@ namespace android { LayerBE::LayerBE() - : mBufferSlot(BufferQueue::INVALID_BUFFER_SLOT), - mBuffer(nullptr), - mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2) { + : mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2) { } @@ -257,9 +254,9 @@ Rect Layer::getContentCrop() const { if (!mCurrentCrop.isEmpty()) { // if the buffer crop is defined, we use that crop = mCurrentCrop; - } else if (getBE().mBuffer != NULL) { + } else if (getBE().compositionInfo.mBuffer != NULL) { // otherwise we use the whole buffer - crop = getBE().mBuffer->getBounds(); + crop = getBE().compositionInfo.mBuffer->getBounds(); } else { // if we don't have a buffer yet, we use an empty/invalid crop crop.makeInvalid(); @@ -1002,9 +999,9 @@ uint32_t Layer::doTransaction(uint32_t flags) { // to the old buffer. However in the state where we don't have an old buffer // there is no such concern but we may still be being used as a parent layer. const bool resizePending = ((c.requested.w != c.active.w) || (c.requested.h != c.active.h)) && - (getBE().mBuffer != nullptr); + (getBE().compositionInfo.mBuffer != nullptr); if (!isFixedSize()) { - if (resizePending && getBE().mSidebandStream == NULL) { + if (resizePending && getBE().compositionInfo.hwc.sidebandStream == nullptr) { flags |= eDontUpdateGeometryState; } } @@ -1401,7 +1398,7 @@ LayerDebugInfo Layer::getLayerDebugInfo() const { info.mMatrix[1][0] = ds.active.transform[1][0]; info.mMatrix[1][1] = ds.active.transform[1][1]; { - sp buffer = getBE().mBuffer; + sp buffer = getBE().compositionInfo.mBuffer; if (buffer != 0) { info.mActiveBufferWidth = buffer->getWidth(); info.mActiveBufferHeight = buffer->getHeight(); @@ -1759,15 +1756,15 @@ Transform Layer::getTransform() const { // for in the transform. We need to mirror this scaling in child surfaces // or we will break the contract where WM can treat child surfaces as // pixels in the parent surface. - if (p->isFixedSize() && p->getBE().mBuffer != nullptr) { + if (p->isFixedSize() && p->getBE().compositionInfo.mBuffer != nullptr) { int bufferWidth; int bufferHeight; if ((p->mCurrentTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) == 0) { - bufferWidth = p->getBE().mBuffer->getWidth(); - bufferHeight = p->getBE().mBuffer->getHeight(); + bufferWidth = p->getBE().compositionInfo.mBuffer->getWidth(); + bufferHeight = p->getBE().compositionInfo.mBuffer->getHeight(); } else { - bufferHeight = p->getBE().mBuffer->getWidth(); - bufferWidth = p->getBE().mBuffer->getHeight(); + bufferHeight = p->getBE().compositionInfo.mBuffer->getWidth(); + bufferWidth = p->getBE().compositionInfo.mBuffer->getHeight(); } float sx = p->getDrawingState().active.w / static_cast(bufferWidth); float sy = p->getDrawingState().active.h / static_cast(bufferHeight); @@ -1867,7 +1864,7 @@ void Layer::writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet) layerInfo->set_z_order_relative_of(zOrderRelativeOf->sequence); } - auto buffer = getBE().mBuffer; + auto buffer = getBE().compositionInfo.mBuffer; if (buffer != nullptr) { LayerProtoHelper::writeToProto(buffer, layerInfo->mutable_active_buffer()); } diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 7c6bc59cfa..9a98e1e2a6 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -31,6 +31,7 @@ #include #include +#include #include @@ -66,15 +67,37 @@ class LayerBE; // --------------------------------------------------------------------------- +struct CompositionInfo { + HWC2::Composition compositionType; + sp mBuffer = nullptr; + int mBufferSlot = BufferQueue::INVALID_BUFFER_SLOT; + struct { + HWComposer* hwc; + sp fence; + HWC2::BlendMode blendMode; + Rect displayFrame; + float alpha; + FloatRect sourceCrop; + HWC2::Transform transform; + int z; + int type; + int appId; + Region visibleRegion; + Region surfaceDamage; + sp sidebandStream; + android_dataspace dataspace; + hwc_color_t color; + } hwc; + struct { + RenderEngine* renderEngine; + Mesh* mesh; + } renderEngine; +}; + class LayerBE { public: LayerBE(); - // main thread - int mBufferSlot; - sp mBuffer; - sp mSidebandStream; - // The mesh used to draw the layer in GLES composition mode Mesh mMesh; @@ -102,6 +125,8 @@ public: // case we need to keep track. In non-mirror mode, a layer will have only one // HWCInfo. This map key is a display layerStack. std::unordered_map mHwcLayers; + + CompositionInfo compositionInfo; }; class Layer : public virtual RefBase { @@ -339,6 +364,7 @@ public: void forceClientComposition(int32_t hwcId); bool getForceClientComposition(int32_t hwcId); virtual void setPerFrameData(const sp& displayDevice) = 0; + void setUpFrameBuffer(const sp& displayDevice); // callIntoHwc exists so we can update our local state and call // acceptDisplayChanges without unnecessarily updating the device's state -- cgit v1.2.3-59-g8ed1b From 577c896102ebb13f9496a94674b4ca9cd15fe0ad Mon Sep 17 00:00:00 2001 From: David Sodman Date: Fri, 8 Dec 2017 14:50:53 -0800 Subject: SurfaceFlinger: Move generic dtor logic to Layer Move Layer generic code from BufferLayer destructor to the Layer destructor so that ColorLayer will be able to use it. Bug: 69127378 Test: CTS SurfaceView tests Change-Id: Ie48ee2c3433e80bcae822654d4dc186d09c49c00 --- services/surfaceflinger/BufferLayer.cpp | 11 ----------- services/surfaceflinger/Layer.cpp | 11 +++++++++++ 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'services/surfaceflinger/BufferLayer.cpp') diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index e8f4150135..7d9d4f6969 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -75,17 +75,6 @@ BufferLayer::BufferLayer(SurfaceFlinger* flinger, const sp& client, cons } BufferLayer::~BufferLayer() { - sp c(mClientRef.promote()); - if (c != 0) { - c->detachLayer(this); - } - - for (auto& point : mRemoteSyncPoints) { - point->setTransactionApplied(); - } - for (auto& point : mLocalSyncPoints) { - point->setFrameAvailable(); - } mFlinger->deleteTextureAsync(mTextureName); if (!getBE().mHwcLayers.empty()) { diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index fa4d289249..13df1e21b4 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -142,6 +142,17 @@ Layer::Layer(SurfaceFlinger* flinger, const sp& client, const String8& n void Layer::onFirstRef() {} Layer::~Layer() { + sp c(mClientRef.promote()); + if (c != 0) { + c->detachLayer(this); + } + + for (auto& point : mRemoteSyncPoints) { + point->setTransactionApplied(); + } + for (auto& point : mLocalSyncPoints) { + point->setFrameAvailable(); + } mFrameTracker.logAndResetStats(mName); } -- cgit v1.2.3-59-g8ed1b From 0cb75ac1daa903c04054aea50869076047b09897 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Mon, 27 Nov 2017 15:56:04 -0800 Subject: surfaceflinger: remove SurfaceFlingerConsumer Move everything into the base class, BufferLayerConsumer. Test: boots Change-Id: I62cd88d1bd0c7686f8c44e7b70cf216ffc2fba89 --- services/surfaceflinger/Android.mk | 1 - services/surfaceflinger/BufferLayer.cpp | 4 +- services/surfaceflinger/BufferLayer.h | 10 ++--- services/surfaceflinger/BufferLayerConsumer.cpp | 10 +++++ services/surfaceflinger/BufferLayerConsumer.h | 5 +++ services/surfaceflinger/LayerRejecter.h | 4 +- services/surfaceflinger/SurfaceFlingerConsumer.cpp | 50 ---------------------- services/surfaceflinger/SurfaceFlingerConsumer.h | 49 --------------------- 8 files changed, 24 insertions(+), 109 deletions(-) delete mode 100644 services/surfaceflinger/SurfaceFlingerConsumer.cpp delete mode 100644 services/surfaceflinger/SurfaceFlingerConsumer.h (limited to 'services/surfaceflinger/BufferLayer.cpp') diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk index 788b851fb8..809cec2626 100644 --- a/services/surfaceflinger/Android.mk +++ b/services/surfaceflinger/Android.mk @@ -22,7 +22,6 @@ LOCAL_SRC_FILES := \ MessageQueue.cpp \ MonitoredProducer.cpp \ SurfaceFlinger.cpp \ - SurfaceFlingerConsumer.cpp \ SurfaceInterceptor.cpp \ SurfaceTracing.cpp \ Transform.cpp \ diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index 7d9d4f6969..b52bef31c7 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -435,7 +435,7 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime // layer update so we check again at the next opportunity. mFlinger->signalLayerUpdate(); return outDirtyRegion; - } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) { + } else if (updateResult == BufferLayerConsumer::BUFFER_REJECTED) { // If the buffer has been rejected, remove it from the shadow queue // and return early if (queuedBuffer) { @@ -660,7 +660,7 @@ void BufferLayer::onFirstRef() { sp consumer; BufferQueue::createBufferQueue(&producer, &consumer, true); mProducer = new MonitoredProducer(producer, mFlinger, this); - mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName, this); + mSurfaceFlingerConsumer = new BufferLayerConsumer(consumer, mTextureName, this); mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0)); mSurfaceFlingerConsumer->setContentsChangedListener(this); mSurfaceFlingerConsumer->setName(mName); diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h index 1127952737..fbe6367306 100644 --- a/services/surfaceflinger/BufferLayer.h +++ b/services/surfaceflinger/BufferLayer.h @@ -16,6 +16,7 @@ #pragma once +#include "BufferLayerConsumer.h" #include "Client.h" #include "Layer.h" #include "DisplayHardware/HWComposer.h" @@ -26,7 +27,6 @@ #include "RenderEngine/Mesh.h" #include "RenderEngine/Texture.h" #include "SurfaceFlinger.h" -#include "SurfaceFlingerConsumer.h" #include "Transform.h" #include @@ -48,13 +48,13 @@ namespace android { /* - * A new BufferQueue and a new SurfaceFlingerConsumer are created when the + * A new BufferQueue and a new BufferLayerConsumer are created when the * BufferLayer is first referenced. * * This also implements onFrameAvailable(), which notifies SurfaceFlinger * that new data has arrived. */ -class BufferLayer : public Layer, public SurfaceFlingerConsumer::ContentsChangedListener { +class BufferLayer : public Layer, public BufferLayerConsumer::ContentsChangedListener { public: BufferLayer(SurfaceFlinger* flinger, const sp& client, const String8& name, uint32_t w, uint32_t h, uint32_t flags); @@ -137,7 +137,7 @@ private: void onFirstRef() override; // Interface implementation for - // SurfaceFlingerConsumer::ContentsChangedListener + // BufferLayerConsumer::ContentsChangedListener void onFrameAvailable(const BufferItem& item) override; void onFrameReplaced(const BufferItem& item) override; void onSidebandStreamChanged() override; @@ -170,7 +170,7 @@ public: sp getProducer() const; private: - sp mSurfaceFlingerConsumer; + sp mSurfaceFlingerConsumer; // Check all of the local sync points to ensure that all transactions // which need to have been applied prior to the frame which is about to diff --git a/services/surfaceflinger/BufferLayerConsumer.cpp b/services/surfaceflinger/BufferLayerConsumer.cpp index 3ebc959608..5569dfac9f 100644 --- a/services/surfaceflinger/BufferLayerConsumer.cpp +++ b/services/surfaceflinger/BufferLayerConsumer.cpp @@ -270,6 +270,11 @@ status_t BufferLayerConsumer::updateTexImage(BufferRejecter* rejecter, const Dis return err; } +status_t BufferLayerConsumer::bindTextureImage() { + Mutex::Autolock lock(mMutex); + return bindTextureImageLocked(); +} + void BufferLayerConsumer::setReleaseFence(const sp& fence) { if (!fence->isValid()) { return; @@ -304,6 +309,11 @@ bool BufferLayerConsumer::releasePendingBuffer() { return true; } +sp BufferLayerConsumer::getPrevFinalReleaseFence() const { + Mutex::Autolock lock(mMutex); + return ConsumerBase::mPrevFinalReleaseFence; +} + status_t BufferLayerConsumer::acquireBufferLocked(BufferItem* item, nsecs_t presentWhen, uint64_t maxFrameNumber) { status_t err = ConsumerBase::acquireBufferLocked(item, presentWhen, maxFrameNumber); diff --git a/services/surfaceflinger/BufferLayerConsumer.h b/services/surfaceflinger/BufferLayerConsumer.h index 4f8e5fadec..cc35a66f24 100644 --- a/services/surfaceflinger/BufferLayerConsumer.h +++ b/services/surfaceflinger/BufferLayerConsumer.h @@ -96,6 +96,9 @@ public: status_t updateTexImage(BufferRejecter* rejecter, const DispSync& dispSync, bool* autoRefresh, bool* queuedBuffer, uint64_t maxFrameNumber); + // See BufferLayerConsumer::bindTextureImageLocked(). + status_t bindTextureImage(); + // setReleaseFence stores a fence that will signal when the current buffer // is no longer being read. This fence will be returned to the producer // when the current buffer is released by updateTexImage(). Multiple @@ -105,6 +108,8 @@ public: bool releasePendingBuffer(); + sp getPrevFinalReleaseFence() const; + // getTransformMatrix retrieves the 4x4 texture coordinate transform matrix // associated with the texture image set by the most recent call to // updateTexImage. diff --git a/services/surfaceflinger/LayerRejecter.h b/services/surfaceflinger/LayerRejecter.h index 828cd8b96e..40972aac87 100644 --- a/services/surfaceflinger/LayerRejecter.h +++ b/services/surfaceflinger/LayerRejecter.h @@ -18,10 +18,10 @@ #define ANDROID_LAYER_REJECTER_H #include "Layer.h" -#include "SurfaceFlingerConsumer.h" +#include "BufferLayerConsumer.h" namespace android { - class LayerRejecter : public SurfaceFlingerConsumer::BufferRejecter { + class LayerRejecter : public BufferLayerConsumer::BufferRejecter { public: LayerRejecter(Layer::State &front, Layer::State ¤t, diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.cpp b/services/surfaceflinger/SurfaceFlingerConsumer.cpp deleted file mode 100644 index 8b64932d91..0000000000 --- a/services/surfaceflinger/SurfaceFlingerConsumer.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define ATRACE_TAG ATRACE_TAG_GRAPHICS -//#define LOG_NDEBUG 0 - -#include "SurfaceFlingerConsumer.h" -#include "Layer.h" - -#include - -#include -#include - -#include -#include -#include - -namespace android { - -// --------------------------------------------------------------------------- - -status_t SurfaceFlingerConsumer::bindTextureImage() -{ - Mutex::Autolock lock(mMutex); - - return bindTextureImageLocked(); -} - -sp SurfaceFlingerConsumer::getPrevFinalReleaseFence() const { - Mutex::Autolock lock(mMutex); - return ConsumerBase::mPrevFinalReleaseFence; -} - -// --------------------------------------------------------------------------- -}; // namespace android - diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.h b/services/surfaceflinger/SurfaceFlingerConsumer.h deleted file mode 100644 index bea5fcb59d..0000000000 --- a/services/surfaceflinger/SurfaceFlingerConsumer.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_SURFACEFLINGERCONSUMER_H -#define ANDROID_SURFACEFLINGERCONSUMER_H - -#include "BufferLayerConsumer.h" -#include "DispSync.h" - -#include - -namespace android { -// ---------------------------------------------------------------------------- - -class Layer; - -/* - * This is a thin wrapper around BufferLayerConsumer. - */ -class SurfaceFlingerConsumer : public BufferLayerConsumer { -public: - SurfaceFlingerConsumer(const sp& consumer, - uint32_t tex, Layer* layer) - : BufferLayerConsumer(consumer, tex, layer) - {} - - // See BufferLayerConsumer::bindTextureImageLocked(). - status_t bindTextureImage(); - - sp getPrevFinalReleaseFence() const; -}; - -// ---------------------------------------------------------------------------- -}; // namespace android - -#endif // ANDROID_SURFACEFLINGERCONSUMER_H -- cgit v1.2.3-59-g8ed1b From 9f2db77e6e342c6bebc3010a900fd6fb98738587 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Thu, 30 Nov 2017 21:06:50 -0800 Subject: surfaceflinger: pass RenderEngine into BufferLayerConsumer Add RenderEngine::isCurrent to replace BufferLayerConsumer::checkAndUpdateEglStateLocked. Remove a duplicated check in updateAndReleaseLocked. Use RenderEngine::checkErrors. Test: SurfaceFlinger_test Change-Id: I6b97534a41a855d101965b498cb1afa72404227e --- services/surfaceflinger/BufferLayer.cpp | 3 +- services/surfaceflinger/BufferLayerConsumer.cpp | 80 +++++----------------- services/surfaceflinger/BufferLayerConsumer.h | 26 +++---- .../surfaceflinger/RenderEngine/RenderEngine.cpp | 4 ++ .../surfaceflinger/RenderEngine/RenderEngine.h | 7 +- 5 files changed, 34 insertions(+), 86 deletions(-) (limited to 'services/surfaceflinger/BufferLayer.cpp') diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index b52bef31c7..1cc37c7af2 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -660,7 +660,8 @@ void BufferLayer::onFirstRef() { sp consumer; BufferQueue::createBufferQueue(&producer, &consumer, true); mProducer = new MonitoredProducer(producer, mFlinger, this); - mSurfaceFlingerConsumer = new BufferLayerConsumer(consumer, mTextureName, this); + mSurfaceFlingerConsumer = new BufferLayerConsumer(consumer, + mFlinger->getRenderEngine(), mTextureName, this); mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0)); mSurfaceFlingerConsumer->setContentsChangedListener(this); mSurfaceFlingerConsumer->setName(mName); diff --git a/services/surfaceflinger/BufferLayerConsumer.cpp b/services/surfaceflinger/BufferLayerConsumer.cpp index 5569dfac9f..b86e54217f 100644 --- a/services/surfaceflinger/BufferLayerConsumer.cpp +++ b/services/surfaceflinger/BufferLayerConsumer.cpp @@ -23,6 +23,7 @@ #include "DispSync.h" #include "Layer.h" +#include "RenderEngine/RenderEngine.h" #include @@ -108,8 +109,8 @@ static bool isEglImageCroppable(const Rect& crop) { return hasEglAndroidImageCrop() && (crop.left == 0 && crop.top == 0); } -BufferLayerConsumer::BufferLayerConsumer(const sp& bq, uint32_t tex, - Layer* layer) +BufferLayerConsumer::BufferLayerConsumer(const sp& bq, RenderEngine& engine, + uint32_t tex, Layer* layer) : ConsumerBase(bq, false), mCurrentCrop(Rect::EMPTY_RECT), mCurrentTransform(0), @@ -123,10 +124,10 @@ BufferLayerConsumer::BufferLayerConsumer(const sp& bq, u mDefaultWidth(1), mDefaultHeight(1), mFilteringEnabled(true), + mRE(engine), + mEglDisplay(mRE.getEGLDisplay()), mTexName(tex), mLayer(layer), - mEglDisplay(EGL_NO_DISPLAY), - mEglContext(EGL_NO_CONTEXT), mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT) { BLC_LOGV("BufferLayerConsumer"); @@ -211,10 +212,10 @@ status_t BufferLayerConsumer::updateTexImage(BufferRejecter* rejecter, const Dis return NO_INIT; } - // Make sure the EGL state is the same as in previous calls. - status_t err = checkAndUpdateEglStateLocked(); - if (err != NO_ERROR) { - return err; + // Make sure RenderEngine is current + if (!mRE.isCurrent()) { + BLC_LOGE("updateTexImage: RenderEngine is not current"); + return INVALID_OPERATION; } BufferItem item; @@ -222,7 +223,7 @@ status_t BufferLayerConsumer::updateTexImage(BufferRejecter* rejecter, const Dis // Acquire the next buffer. // In asynchronous mode the list is guaranteed to be one buffer // deep, while in synchronous mode we use the oldest buffer. - err = acquireBufferLocked(&item, computeExpectedPresent(dispSync), maxFrameNumber); + status_t err = acquireBufferLocked(&item, computeExpectedPresent(dispSync), maxFrameNumber); if (err != NO_ERROR) { if (err == BufferQueue::NO_BUFFER_AVAILABLE) { err = NO_ERROR; @@ -338,13 +339,6 @@ status_t BufferLayerConsumer::updateAndReleaseLocked(const BufferItem& item, int slot = item.mSlot; - // Confirm state. - err = checkAndUpdateEglStateLocked(); - if (err != NO_ERROR) { - releaseBufferLocked(slot, mSlots[slot].mGraphicBuffer); - return err; - } - // Ensure we have a valid EglImageKHR for the slot, creating an EglImage // if nessessary, for the gralloc buffer currently in the slot in // ConsumerBase. @@ -418,15 +412,7 @@ status_t BufferLayerConsumer::updateAndReleaseLocked(const BufferItem& item, } status_t BufferLayerConsumer::bindTextureImageLocked() { - if (mEglDisplay == EGL_NO_DISPLAY) { - ALOGE("bindTextureImage: invalid display"); - return INVALID_OPERATION; - } - - GLenum error; - while ((error = glGetError()) != GL_NO_ERROR) { - BLC_LOGW("bindTextureImage: clearing GL error: %#04x", error); - } + mRE.checkErrors(); glBindTexture(sTexTarget, mTexName); if (mCurrentTexture == BufferQueue::INVALID_BUFFER_SLOT && mCurrentTextureImage == NULL) { @@ -446,32 +432,6 @@ status_t BufferLayerConsumer::bindTextureImageLocked() { return doGLFenceWaitLocked(); } -status_t BufferLayerConsumer::checkAndUpdateEglStateLocked() { - EGLDisplay dpy = eglGetCurrentDisplay(); - EGLContext ctx = eglGetCurrentContext(); - - // if this is the first time we're called, mEglDisplay/mEglContext have - // never been set, so don't error out (below). - if (mEglDisplay == EGL_NO_DISPLAY) { - mEglDisplay = dpy; - } - if (mEglContext == EGL_NO_CONTEXT) { - mEglContext = ctx; - } - - if (mEglDisplay != dpy || dpy == EGL_NO_DISPLAY) { - BLC_LOGE("checkAndUpdateEglState: invalid current EGLDisplay"); - return INVALID_OPERATION; - } - - if (mEglContext != ctx || ctx == EGL_NO_CONTEXT) { - BLC_LOGE("checkAndUpdateEglState: invalid current EGLContext"); - return INVALID_OPERATION; - } - - return NO_ERROR; -} - status_t BufferLayerConsumer::syncForReleaseLocked(EGLDisplay dpy) { BLC_LOGV("syncForReleaseLocked"); @@ -608,16 +568,8 @@ std::shared_ptr BufferLayerConsumer::getCurrentFenceTime() const { } status_t BufferLayerConsumer::doGLFenceWaitLocked() const { - EGLDisplay dpy = eglGetCurrentDisplay(); - EGLContext ctx = eglGetCurrentContext(); - - if (mEglDisplay != dpy || mEglDisplay == EGL_NO_DISPLAY) { - BLC_LOGE("doGLFenceWait: invalid current EGLDisplay"); - return INVALID_OPERATION; - } - - if (mEglContext != ctx || mEglContext == EGL_NO_CONTEXT) { - BLC_LOGE("doGLFenceWait: invalid current EGLContext"); + if (!mRE.isCurrent()) { + BLC_LOGE("doGLFenceWait: RenderEngine is not current"); return INVALID_OPERATION; } @@ -630,7 +582,7 @@ status_t BufferLayerConsumer::doGLFenceWaitLocked() const { return -errno; } EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fenceFd, EGL_NONE}; - EGLSyncKHR sync = eglCreateSyncKHR(dpy, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs); + EGLSyncKHR sync = eglCreateSyncKHR(mEglDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs); if (sync == EGL_NO_SYNC_KHR) { close(fenceFd); BLC_LOGE("doGLFenceWait: error creating EGL fence: %#x", eglGetError()); @@ -640,9 +592,9 @@ status_t BufferLayerConsumer::doGLFenceWaitLocked() const { // XXX: The spec draft is inconsistent as to whether this should // return an EGLint or void. Ignore the return value for now, as // it's not strictly needed. - eglWaitSyncKHR(dpy, sync, 0); + eglWaitSyncKHR(mEglDisplay, sync, 0); EGLint eglErr = eglGetError(); - eglDestroySyncKHR(dpy, sync); + eglDestroySyncKHR(mEglDisplay, sync); if (eglErr != EGL_SUCCESS) { BLC_LOGE("doGLFenceWait: error waiting for EGL fence: %#x", eglErr); return UNKNOWN_ERROR; diff --git a/services/surfaceflinger/BufferLayerConsumer.h b/services/surfaceflinger/BufferLayerConsumer.h index cc35a66f24..a08f15b248 100644 --- a/services/surfaceflinger/BufferLayerConsumer.h +++ b/services/surfaceflinger/BufferLayerConsumer.h @@ -36,6 +36,7 @@ namespace android { class DispSync; class Layer; +class RenderEngine; class String8; /* @@ -73,7 +74,8 @@ public: // BufferLayerConsumer constructs a new BufferLayerConsumer object. // The tex parameter indicates the name of the OpenGL ES // texture to which images are to be streamed. - BufferLayerConsumer(const sp& bq, uint32_t tex, Layer* layer); + BufferLayerConsumer(const sp& bq, RenderEngine& engine, uint32_t tex, + Layer* layer); // Sets the contents changed listener. This should be used instead of // ConsumerBase::setFrameAvailableListener(). @@ -230,12 +232,6 @@ protected: // bind succeeds, this calls doGLFenceWait. status_t bindTextureImageLocked(); - // Gets the current EGLDisplay and EGLContext values, and compares them - // to mEglDisplay and mEglContext. If the fields have been previously - // set, the values must match; if not, the fields are set to the current - // values. - status_t checkAndUpdateEglStateLocked(); - private: // EglImage is a utility class for tracking and creating EGLImageKHRs. There // is primarily just one image per slot, but there is also special cases: @@ -381,6 +377,11 @@ private: // setFilteringEnabled(). bool mFilteringEnabled; + RenderEngine& mRE; + + // mEglDisplay is initialized to RenderEngine's EGLDisplay. + const EGLDisplay mEglDisplay; + // mTexName is the name of the OpenGL texture to which streamed images will // be bound when updateTexImage is called. It is set at construction time. const uint32_t mTexName; @@ -397,17 +398,6 @@ private: sp mEglImage; }; - // mEglDisplay is the EGLDisplay with which this BufferLayerConsumer is currently - // associated. It is intialized to EGL_NO_DISPLAY and gets set to the - // current display when updateTexImage is called for the first time. - EGLDisplay mEglDisplay; - - // mEglContext is the OpenGL ES context with which this BufferLayerConsumer is - // currently associated. It is initialized to EGL_NO_CONTEXT and gets set - // to the current GL context when updateTexImage is called for the first - // time. - EGLContext mEglContext; - // mEGLSlots stores the buffers that have been allocated by the BufferQueue // for each buffer slot. It is initialized to null pointers, and gets // filled in with the result of BufferQueue::acquire when the diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.cpp b/services/surfaceflinger/RenderEngine/RenderEngine.cpp index f1415c9757..314333f044 100644 --- a/services/surfaceflinger/RenderEngine/RenderEngine.cpp +++ b/services/surfaceflinger/RenderEngine/RenderEngine.cpp @@ -157,6 +157,10 @@ bool RenderEngine::supportsImageCrop() const { return GLExtensions::getInstance().hasImageCrop(); } +bool RenderEngine::isCurrent() const { + return mEGLDisplay == eglGetCurrentDisplay() && mEGLContext == eglGetCurrentContext(); +} + bool RenderEngine::setCurrentSurface(const RE::Surface& surface) { bool success = true; EGLSurface eglSurface = surface.getEGLSurface(); diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.h b/services/surfaceflinger/RenderEngine/RenderEngine.h index 57662a4152..f8869197b1 100644 --- a/services/surfaceflinger/RenderEngine/RenderEngine.h +++ b/services/surfaceflinger/RenderEngine/RenderEngine.h @@ -86,6 +86,10 @@ public: bool supportsImageCrop() const; + bool isCurrent() const; + bool setCurrentSurface(const RE::Surface& surface); + void resetCurrentSurface(); + // synchronization // flush submits RenderEngine command stream for execution and returns a @@ -124,9 +128,6 @@ public: int getStatus() const; }; - bool setCurrentSurface(const RE::Surface& surface); - void resetCurrentSurface(); - // set-up virtual void checkErrors() const; virtual void setViewportAndProjection(size_t vpw, size_t vph, Rect sourceCrop, size_t hwh, -- cgit v1.2.3-59-g8ed1b From 80d611613ef1a9c05a31cd3f47badfd4de9b1418 Mon Sep 17 00:00:00 2001 From: Dan Stoza Date: Wed, 20 Dec 2017 15:57:52 -0800 Subject: SF: Switch computeBounds to return FloatRect Switches Layer::computeBounds to return a FloatRect instead of a Rect. During the computation of the bounds, we apply the layer transformation to its nominal dimensions, clip it against its bounds (which are either its parents bounds or the screen bounds), and apply the inverse of the layer transformation. Previously, the intermediate position (after transformation/clip, but before inverse transformation) was stored as Rect, which is to say that it was truncated to integer coordinates. After applying the inverse transformation, this loss of precision can cause glitches where a layer that should be clipped against, e.g., the side of the screen no longer creates a watertight seal against that side. In order to fix this, we now store the intermediate value as a FloatRect and propagate float precision back through computeBounds. The callers of computeBounds tend to then immediately apply the transform again, at which point it is safe to round back to integer. Bug: 64070729 Bug: 66431327 Bug: 69935057 Test: Modified android.view.cts.SurfaceViewSyncTest# testSurfaceViewBigScale no longer produces bogus display frames Change-Id: If5987ca4ad76657f9670a5f59258f896180352e2 --- libs/ui/include/ui/FloatRect.h | 11 +++++++++++ libs/ui/include/ui/Rect.h | 9 +++++++++ services/surfaceflinger/BufferLayer.cpp | 5 +++-- services/surfaceflinger/Layer.cpp | 28 ++++++++++++++++++++-------- services/surfaceflinger/Layer.h | 5 +++-- services/surfaceflinger/Transform.cpp | 21 +++++++++++++++++++++ services/surfaceflinger/Transform.h | 1 + 7 files changed, 68 insertions(+), 12 deletions(-) (limited to 'services/surfaceflinger/BufferLayer.cpp') diff --git a/libs/ui/include/ui/FloatRect.h b/libs/ui/include/ui/FloatRect.h index 270675cba2..6a7479a68a 100644 --- a/libs/ui/include/ui/FloatRect.h +++ b/libs/ui/include/ui/FloatRect.h @@ -27,6 +27,17 @@ public: float getWidth() const { return right - left; } float getHeight() const { return bottom - top; } + FloatRect intersect(const FloatRect& other) const { + return { + // Inline to avoid tromping on other min/max defines or adding a + // dependency on STL + (left > other.left) ? left : other.left, + (top > other.top) ? top : other.top, + (right < other.right) ? right : other.right, + (bottom < other.bottom) ? bottom : other.bottom + }; + } + float left = 0.0f; float top = 0.0f; float right = 0.0f; diff --git a/libs/ui/include/ui/Rect.h b/libs/ui/include/ui/Rect.h index 437fc14504..0bec0b7f78 100644 --- a/libs/ui/include/ui/Rect.h +++ b/libs/ui/include/ui/Rect.h @@ -69,6 +69,15 @@ public: bottom = rb.y; } + inline explicit Rect(const FloatRect& floatRect) { + // Ideally we would use std::round, but we don't want to add an STL + // dependency here, so we use an approximation + left = static_cast(floatRect.left + 0.5f); + top = static_cast(floatRect.top + 0.5f); + right = static_cast(floatRect.right + 0.5f); + bottom = static_cast(floatRect.bottom + 0.5f); + } + void makeInvalid(); inline void clear() { diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index b52bef31c7..f16e1bad5d 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -787,16 +787,17 @@ void BufferLayer::drawWithOpenGL(const RenderArea& renderArea, bool useIdentityT * minimal value)? Or, we could make GL behave like HWC -- but this feel * like more of a hack. */ - Rect win(computeBounds()); + const Rect bounds{computeBounds()}; // Rounds from FloatRect Transform t = getTransform(); + Rect win = bounds; if (!s.finalCrop.isEmpty()) { win = t.transform(win); if (!win.intersect(s.finalCrop, &win)) { win.clear(); } win = t.inverse().transform(win); - if (!win.intersect(computeBounds(), &win)) { + if (!win.intersect(bounds, &win)) { win.clear(); } } diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 13df1e21b4..a5d0c3a278 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -285,6 +285,14 @@ static Rect reduce(const Rect& win, const Region& exclude) { return Region(win).subtract(exclude).getBounds(); } +static FloatRect reduce(const FloatRect& win, const Region& exclude) { + if (CC_LIKELY(exclude.isEmpty())) { + return win; + } + // Convert through Rect (by rounding) for lack of FloatRegion + return Region(Rect{win}).subtract(exclude).getBounds().toFloatRect(); +} + Rect Layer::computeScreenBounds(bool reduceTransparentRegion) const { const Layer::State& s(getDrawingState()); Rect win(s.active.w, s.active.h); @@ -323,12 +331,12 @@ Rect Layer::computeScreenBounds(bool reduceTransparentRegion) const { return win; } -Rect Layer::computeBounds() const { +FloatRect Layer::computeBounds() const { const Layer::State& s(getDrawingState()); return computeBounds(s.activeTransparentRegion); } -Rect Layer::computeBounds(const Region& activeTransparentRegion) const { +FloatRect Layer::computeBounds(const Region& activeTransparentRegion) const { const Layer::State& s(getDrawingState()); Rect win(s.active.w, s.active.h); @@ -345,14 +353,16 @@ Rect Layer::computeBounds(const Region& activeTransparentRegion) const { } Transform t = getTransform(); + + FloatRect floatWin = win.toFloatRect(); if (p != nullptr) { - win = t.transform(win); - win.intersect(bounds, &win); - win = t.inverse().transform(win); + floatWin = t.transform(floatWin); + floatWin = floatWin.intersect(bounds.toFloatRect()); + floatWin = t.inverse().transform(floatWin); } // subtract the transparent region and snap to the bounds - return reduce(win, activeTransparentRegion); + return reduce(floatWin, activeTransparentRegion); } Rect Layer::computeInitialCrop(const sp& hw) const { @@ -528,7 +538,9 @@ void Layer::setGeometry(const sp& displayDevice, uint32_t z Rect(activeCrop.right, activeCrop.top, s.active.w, activeCrop.bottom)); } - Rect frame(t.transform(computeBounds(activeTransparentRegion))); + // computeBounds returns a FloatRect to provide more accuracy during the + // transformation. We then round upon constructing 'frame'. + Rect frame{t.transform(computeBounds(activeTransparentRegion))}; if (!s.finalCrop.isEmpty()) { if (!frame.intersect(s.finalCrop, &frame)) { frame.clear(); @@ -807,7 +819,7 @@ void Layer::computeGeometry(const RenderArea& renderArea, Mesh& mesh, const Layer::State& s(getDrawingState()); const Transform renderAreaTransform(renderArea.getTransform()); const uint32_t height = renderArea.getHeight(); - Rect win = computeBounds(); + FloatRect win = computeBounds(); vec2 lt = vec2(win.left, win.top); vec2 lb = vec2(win.left, win.bottom); diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index cf7fc508e8..e44ccf8d57 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -303,8 +304,8 @@ public: } void computeGeometry(const RenderArea& renderArea, Mesh& mesh, bool useIdentityTransform) const; - Rect computeBounds(const Region& activeTransparentRegion) const; - Rect computeBounds() const; + FloatRect computeBounds(const Region& activeTransparentRegion) const; + FloatRect computeBounds() const; int32_t getSequence() const { return sequence; } diff --git a/services/surfaceflinger/Transform.cpp b/services/surfaceflinger/Transform.cpp index 37925a1641..e05ed5375e 100644 --- a/services/surfaceflinger/Transform.cpp +++ b/services/surfaceflinger/Transform.cpp @@ -224,6 +224,27 @@ Rect Transform::transform(const Rect& bounds, bool roundOutwards) const return r; } +FloatRect Transform::transform(const FloatRect& bounds) const +{ + vec2 lt(bounds.left, bounds.top); + vec2 rt(bounds.right, bounds.top); + vec2 lb(bounds.left, bounds.bottom); + vec2 rb(bounds.right, bounds.bottom); + + lt = transform(lt); + rt = transform(rt); + lb = transform(lb); + rb = transform(rb); + + FloatRect r; + r.left = min(lt[0], rt[0], lb[0], rb[0]); + r.top = min(lt[1], rt[1], lb[1], rb[1]); + r.right = max(lt[0], rt[0], lb[0], rb[0]); + r.bottom = max(lt[1], rt[1], lb[1], rb[1]); + + return r; +} + Region Transform::transform(const Region& reg) const { Region out; diff --git a/services/surfaceflinger/Transform.h b/services/surfaceflinger/Transform.h index bfc66eccb9..b11d0576c4 100644 --- a/services/surfaceflinger/Transform.h +++ b/services/surfaceflinger/Transform.h @@ -84,6 +84,7 @@ public: Region transform(const Region& reg) const; Rect transform(const Rect& bounds, bool roundOutwards = false) const; + FloatRect transform(const FloatRect& bounds) const; Transform operator * (const Transform& rhs) const; // assumes the last row is < 0 , 0 , 1 > vec2 transform(const vec2& v) const; -- cgit v1.2.3-59-g8ed1b From b28c6742fa7ce8ff69eebf6b15140730066135d3 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Wed, 27 Dec 2017 10:59:54 -0800 Subject: surfaceflinger: rename BufferLayer::mSurfaceFlingerConsumer Rename mSurfaceFlingerConsumer to mConsumer now that the type is BufferLayerConsumer. Test: builds Change-Id: I22026e3af9e51a5ab3abf2ac32f92b506a70328a --- services/surfaceflinger/BufferLayer.cpp | 66 ++++++++++++++++----------------- services/surfaceflinger/BufferLayer.h | 2 +- 2 files changed, 34 insertions(+), 34 deletions(-) (limited to 'services/surfaceflinger/BufferLayer.cpp') diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index acdfafcd4e..5f70ab54da 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -53,7 +53,7 @@ namespace android { BufferLayer::BufferLayer(SurfaceFlinger* flinger, const sp& client, const String8& name, uint32_t w, uint32_t h, uint32_t flags) : Layer(flinger, client, name, w, h, flags), - mSurfaceFlingerConsumer(nullptr), + mConsumer(nullptr), mTextureName(UINT32_MAX), mFormat(PIXEL_FORMAT_NONE), mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), @@ -89,7 +89,7 @@ void BufferLayer::useSurfaceDamage() { if (mFlinger->mForceFullDamage) { surfaceDamageRegion = Region::INVALID_REGION; } else { - surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage(); + surfaceDamageRegion = mConsumer->getSurfaceDamage(); } } @@ -129,9 +129,9 @@ status_t BufferLayer::setBuffers(uint32_t w, uint32_t h, PixelFormat format, uin mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false; mCurrentOpacity = getOpacityForFormat(format); - mSurfaceFlingerConsumer->setDefaultBufferSize(w, h); - mSurfaceFlingerConsumer->setDefaultBufferFormat(format); - mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0)); + mConsumer->setDefaultBufferSize(w, h); + mConsumer->setDefaultBufferFormat(format); + mConsumer->setConsumerUsageBits(getEffectiveUsage(0)); return NO_ERROR; } @@ -190,7 +190,7 @@ void BufferLayer::onDraw(const RenderArea& renderArea, const Region& clip, // Bind the current buffer to the GL texture, and wait for it to be // ready for us to draw into. - status_t err = mSurfaceFlingerConsumer->bindTextureImage(); + status_t err = mConsumer->bindTextureImage(); if (err != NO_ERROR) { ALOGW("onDraw: bindTextureImage failed (err=%d)", err); // Go ahead and draw the buffer anyway; no matter what we do the screen @@ -207,8 +207,8 @@ void BufferLayer::onDraw(const RenderArea& renderArea, const Region& clip, // Query the texture matrix given our current filtering mode. float textureMatrix[16]; - mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering); - mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix); + mConsumer->setFilteringEnabled(useFiltering); + mConsumer->getTransformMatrix(textureMatrix); if (getTransformToDisplayInverse()) { /* @@ -253,11 +253,11 @@ void BufferLayer::onDraw(const RenderArea& renderArea, const Region& clip, } void BufferLayer::onLayerDisplayed(const sp& releaseFence) { - mSurfaceFlingerConsumer->setReleaseFence(releaseFence); + mConsumer->setReleaseFence(releaseFence); } void BufferLayer::abandon() { - mSurfaceFlingerConsumer->abandon(); + mConsumer->abandon(); } bool BufferLayer::shouldPresentNow(const DispSync& dispSync) const { @@ -270,7 +270,7 @@ bool BufferLayer::shouldPresentNow(const DispSync& dispSync) const { return false; } auto timestamp = mQueueItems[0].mTimestamp; - nsecs_t expectedPresent = mSurfaceFlingerConsumer->computeExpectedPresent(dispSync); + nsecs_t expectedPresent = mConsumer->computeExpectedPresent(dispSync); // Ignore timestamps more than a second in the future bool isPlausible = timestamp < (expectedPresent + s2ns(1)); @@ -284,7 +284,7 @@ bool BufferLayer::shouldPresentNow(const DispSync& dispSync) const { } void BufferLayer::setTransformHint(uint32_t orientation) const { - mSurfaceFlingerConsumer->setTransformHint(orientation); + mConsumer->setTransformHint(orientation); } bool BufferLayer::onPreComposition(nsecs_t refreshStartTime) { @@ -312,10 +312,10 @@ bool BufferLayer::onPostComposition(const std::shared_ptr& glDoneFenc } // Update mFrameTracker. - nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp(); + nsecs_t desiredPresentTime = mConsumer->getTimestamp(); mFrameTracker.setDesiredPresentTime(desiredPresentTime); - std::shared_ptr frameReadyFence = mSurfaceFlingerConsumer->getCurrentFenceTime(); + std::shared_ptr frameReadyFence = mConsumer->getCurrentFenceTime(); if (frameReadyFence->isValid()) { mFrameTracker.setFrameReadyFence(std::move(frameReadyFence)); } else { @@ -340,7 +340,7 @@ bool BufferLayer::onPostComposition(const std::shared_ptr& glDoneFenc std::vector BufferLayer::getOccupancyHistory(bool forceFlush) { std::vector history; - status_t result = mSurfaceFlingerConsumer->getOccupancyHistory(forceFlush, &history); + status_t result = mConsumer->getOccupancyHistory(forceFlush, &history); if (result != NO_ERROR) { ALOGW("[%s] Failed to obtain occupancy history (%d)", mName.string(), result); return {}; @@ -349,16 +349,16 @@ std::vector BufferLayer::getOccupancyHistory(bool for } bool BufferLayer::getTransformToDisplayInverse() const { - return mSurfaceFlingerConsumer->getTransformToDisplayInverse(); + return mConsumer->getTransformToDisplayInverse(); } void BufferLayer::releasePendingBuffer(nsecs_t dequeueReadyTime) { - if (!mSurfaceFlingerConsumer->releasePendingBuffer()) { + if (!mConsumer->releasePendingBuffer()) { return; } auto releaseFenceTime = - std::make_shared(mSurfaceFlingerConsumer->getPrevFinalReleaseFence()); + std::make_shared(mConsumer->getPrevFinalReleaseFence()); mReleaseTimeline.updateSignalTimes(); mReleaseTimeline.push(releaseFenceTime); @@ -374,7 +374,7 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) { // mSidebandStreamChanged was true - mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream(); + mSidebandStream = mConsumer->getSidebandStream(); // replicated in LayerBE until FE/BE is ready to be synchronized getBE().compositionInfo.hwc.sidebandStream = mSidebandStream; if (getBE().compositionInfo.hwc.sidebandStream != NULL) { @@ -427,7 +427,7 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime getProducerStickyTransform() != 0, mName.string(), mOverrideScalingMode, mFreezeGeometryUpdates); status_t updateResult = - mSurfaceFlingerConsumer->updateTexImage(&r, mFlinger->mPrimaryDispSync, + mConsumer->updateTexImage(&r, mFlinger->mPrimaryDispSync, &mAutoRefresh, &queuedBuffer, mLastFrameNumberReceived); if (updateResult == BufferQueue::PRESENT_LATER) { @@ -466,7 +466,7 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime if (queuedBuffer) { // Autolock scope - auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber(); + auto currentFrameNumber = mConsumer->getFrameNumber(); Mutex::Autolock lock(mQueueItemLock); @@ -489,7 +489,7 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime // update the active buffer getBE().compositionInfo.mBuffer = - mSurfaceFlingerConsumer->getCurrentBuffer(&getBE().compositionInfo.mBufferSlot); + mConsumer->getCurrentBuffer(&getBE().compositionInfo.mBufferSlot); // replicated in LayerBE until FE/BE is ready to be synchronized mActiveBuffer = getBE().compositionInfo.mBuffer; if (getBE().compositionInfo.mBuffer == NULL) { @@ -499,7 +499,7 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime mBufferLatched = true; mPreviousFrameNumber = mCurrentFrameNumber; - mCurrentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber(); + mCurrentFrameNumber = mConsumer->getFrameNumber(); { Mutex::Autolock lock(mFrameEventHistoryMutex); @@ -514,11 +514,11 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime recomputeVisibleRegions = true; } - setDataSpace(mSurfaceFlingerConsumer->getCurrentDataSpace()); + setDataSpace(mConsumer->getCurrentDataSpace()); - Rect crop(mSurfaceFlingerConsumer->getCurrentCrop()); - const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform()); - const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode()); + Rect crop(mConsumer->getCurrentCrop()); + const uint32_t transform(mConsumer->getCurrentTransform()); + const uint32_t scalingMode(mConsumer->getCurrentScalingMode()); if ((crop != mCurrentCrop) || (transform != mCurrentTransform) || (scalingMode != mCurrentScalingMode)) { @@ -573,7 +573,7 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime } void BufferLayer::setDefaultBufferSize(uint32_t w, uint32_t h) { - mSurfaceFlingerConsumer->setDefaultBufferSize(w, h); + mConsumer->setDefaultBufferSize(w, h); } void BufferLayer::setPerFrameData(const sp& displayDevice) { @@ -633,7 +633,7 @@ void BufferLayer::setPerFrameData(const sp& displayDevice) hwcInfo.bufferCache.getHwcBuffer(getBE().compositionInfo.mBufferSlot, getBE().compositionInfo.mBuffer, &hwcSlot, &hwcBuffer); - auto acquireFence = mSurfaceFlingerConsumer->getCurrentFence(); + auto acquireFence = mConsumer->getCurrentFence(); error = hwcLayer->setBuffer(hwcSlot, hwcBuffer, acquireFence); if (error != HWC2::Error::None) { ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(), @@ -660,11 +660,11 @@ void BufferLayer::onFirstRef() { sp consumer; BufferQueue::createBufferQueue(&producer, &consumer, true); mProducer = new MonitoredProducer(producer, mFlinger, this); - mSurfaceFlingerConsumer = new BufferLayerConsumer(consumer, + mConsumer = new BufferLayerConsumer(consumer, mFlinger->getRenderEngine(), mTextureName, this); - mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0)); - mSurfaceFlingerConsumer->setContentsChangedListener(this); - mSurfaceFlingerConsumer->setName(mName); + mConsumer->setConsumerUsageBits(getEffectiveUsage(0)); + mConsumer->setContentsChangedListener(this); + mConsumer->setName(mName); if (mFlinger->isLayerTripleBufferingDisabled()) { mProducer->setMaxDequeuedBufferCount(2); diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h index fbe6367306..6b02f8c128 100644 --- a/services/surfaceflinger/BufferLayer.h +++ b/services/surfaceflinger/BufferLayer.h @@ -170,7 +170,7 @@ public: sp getProducer() const; private: - sp mSurfaceFlingerConsumer; + sp mConsumer; // Check all of the local sync points to ensure that all transactions // which need to have been applied prior to the frame which is about to -- cgit v1.2.3-59-g8ed1b From 566a3b4a1d1a2a6d38257113700eea92aa44ea2b Mon Sep 17 00:00:00 2001 From: Peiyong Lin Date: Tue, 9 Jan 2018 18:22:43 -0800 Subject: [SurfaceFlinger] Replace NULL with nullptr. Test: make Change-Id: Ia0ecb3160cd5fddf22fb7100c1759d62e723d0b7 --- services/surfaceflinger/BufferLayer.cpp | 11 ++--- services/surfaceflinger/BufferLayerConsumer.cpp | 20 ++++----- services/surfaceflinger/BufferLayerConsumer.h | 4 +- services/surfaceflinger/Client.cpp | 4 +- services/surfaceflinger/DisplayDevice.cpp | 2 +- .../DisplayHardware/FramebufferSurface.h | 2 +- .../DisplayHardware/HWComposer_hwc1.h | 8 ++-- .../DisplayHardware/VirtualDisplaySurface.cpp | 6 +-- services/surfaceflinger/EventThread.cpp | 4 +- services/surfaceflinger/FrameTracker.cpp | 16 +++---- services/surfaceflinger/FrameTracker.h | 2 +- services/surfaceflinger/Layer.cpp | 2 +- services/surfaceflinger/LayerRejecter.cpp | 2 +- services/surfaceflinger/RenderEngine/Program.cpp | 2 +- .../surfaceflinger/RenderEngine/ProgramCache.cpp | 4 +- .../surfaceflinger/RenderEngine/RenderEngine.cpp | 18 ++++---- services/surfaceflinger/SurfaceFlinger.cpp | 50 +++++++++++----------- .../tests/SurfaceInterceptor_test.cpp | 2 +- services/surfaceflinger/tests/Transaction_test.cpp | 16 +++---- 19 files changed, 88 insertions(+), 87 deletions(-) (limited to 'services/surfaceflinger/BufferLayer.cpp') diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index 5f70ab54da..d860f58509 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -105,7 +105,8 @@ bool BufferLayer::isProtected() const { bool BufferLayer::isVisible() const { return !(isHiddenByPolicy()) && getAlpha() > 0.0f && - (getBE().compositionInfo.mBuffer != NULL || getBE().compositionInfo.hwc.sidebandStream != NULL); + (getBE().compositionInfo.mBuffer != nullptr || + getBE().compositionInfo.hwc.sidebandStream != nullptr); } bool BufferLayer::isFixedSize() const { @@ -377,7 +378,7 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime mSidebandStream = mConsumer->getSidebandStream(); // replicated in LayerBE until FE/BE is ready to be synchronized getBE().compositionInfo.hwc.sidebandStream = mSidebandStream; - if (getBE().compositionInfo.hwc.sidebandStream != NULL) { + if (getBE().compositionInfo.hwc.sidebandStream != nullptr) { setTransactionFlags(eTransactionNeeded); mFlinger->setTransactionFlags(eTraversalNeeded); } @@ -492,7 +493,7 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime mConsumer->getCurrentBuffer(&getBE().compositionInfo.mBufferSlot); // replicated in LayerBE until FE/BE is ready to be synchronized mActiveBuffer = getBE().compositionInfo.mBuffer; - if (getBE().compositionInfo.mBuffer == NULL) { + if (getBE().compositionInfo.mBuffer == nullptr) { // this can only happen if the very first buffer was rejected. return outDirtyRegion; } @@ -508,7 +509,7 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime mRefreshPending = true; mFrameLatencyNeeded = true; - if (oldBuffer == NULL) { + if (oldBuffer == nullptr) { // the first time we receive a buffer, we need to trigger a // geometry invalidation. recomputeVisibleRegions = true; @@ -528,7 +529,7 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime recomputeVisibleRegions = true; } - if (oldBuffer != NULL) { + if (oldBuffer != nullptr) { uint32_t bufWidth = getBE().compositionInfo.mBuffer->getWidth(); uint32_t bufHeight = getBE().compositionInfo.mBuffer->getHeight(); if (bufWidth != uint32_t(oldBuffer->width) || diff --git a/services/surfaceflinger/BufferLayerConsumer.cpp b/services/surfaceflinger/BufferLayerConsumer.cpp index bf61236663..8f5c9c740b 100644 --- a/services/surfaceflinger/BufferLayerConsumer.cpp +++ b/services/surfaceflinger/BufferLayerConsumer.cpp @@ -271,7 +271,7 @@ status_t BufferLayerConsumer::acquireBufferLocked(BufferItem* item, nsecs_t pres // If item->mGraphicBuffer is not null, this buffer has not been acquired // before, so any prior EglImage created is using a stale buffer. This // replaces any old EglImage with a new one (using the new buffer). - if (item->mGraphicBuffer != NULL) { + if (item->mGraphicBuffer != nullptr) { mImages[item->mSlot] = new Image(item->mGraphicBuffer, mRE); } @@ -306,8 +306,8 @@ status_t BufferLayerConsumer::updateAndReleaseLocked(const BufferItem& item, } BLC_LOGV("updateAndRelease: (slot=%d buf=%p) -> (slot=%d buf=%p)", mCurrentTexture, - mCurrentTextureImage != NULL ? mCurrentTextureImage->graphicBufferHandle() : 0, slot, - mSlots[slot].mGraphicBuffer->handle); + mCurrentTextureImage != nullptr ? mCurrentTextureImage->graphicBufferHandle() : 0, + slot, mSlots[slot].mGraphicBuffer->handle); // Hang onto the pointer so that it isn't freed in the call to // releaseBufferLocked() if we're in shared buffer mode and both buffers are @@ -355,7 +355,7 @@ status_t BufferLayerConsumer::updateAndReleaseLocked(const BufferItem& item, status_t BufferLayerConsumer::bindTextureImageLocked() { mRE.checkErrors(); - if (mCurrentTexture == BufferQueue::INVALID_BUFFER_SLOT && mCurrentTextureImage == NULL) { + if (mCurrentTexture == BufferQueue::INVALID_BUFFER_SLOT && mCurrentTextureImage == nullptr) { BLC_LOGE("bindTextureImage: no currently-bound texture"); mRE.bindExternalTextureImage(mTexName, RE::Image(mRE)); return NO_INIT; @@ -414,11 +414,11 @@ void BufferLayerConsumer::setFilteringEnabled(bool enabled) { bool needsRecompute = mFilteringEnabled != enabled; mFilteringEnabled = enabled; - if (needsRecompute && mCurrentTextureImage == NULL) { - BLC_LOGD("setFilteringEnabled called with mCurrentTextureImage == NULL"); + if (needsRecompute && mCurrentTextureImage == nullptr) { + BLC_LOGD("setFilteringEnabled called with mCurrentTextureImage == nullptr"); } - if (needsRecompute && mCurrentTextureImage != NULL) { + if (needsRecompute && mCurrentTextureImage != nullptr) { computeCurrentTransformMatrixLocked(); } } @@ -429,7 +429,7 @@ void BufferLayerConsumer::computeCurrentTransformMatrixLocked() { (mCurrentTextureImage == nullptr) ? nullptr : mCurrentTextureImage->graphicBuffer(); if (buf == nullptr) { BLC_LOGD("computeCurrentTransformMatrixLocked: " - "mCurrentTextureImage is NULL"); + "mCurrentTextureImage is nullptr"); } const Rect& cropRect = canUseImageCrop(mCurrentCrop) ? Rect::EMPTY_RECT : mCurrentCrop; GLConsumer::computeTransformMatrix(mCurrentTransformMatrix, buf, cropRect, mCurrentTransform, @@ -476,7 +476,7 @@ sp BufferLayerConsumer::getCurrentBuffer(int* outSlot) const { *outSlot = mCurrentTexture; } - return (mCurrentTextureImage == nullptr) ? NULL : mCurrentTextureImage->graphicBuffer(); + return (mCurrentTextureImage == nullptr) ? nullptr : mCurrentTextureImage->graphicBuffer(); } Rect BufferLayerConsumer::getCurrentCrop() const { @@ -564,7 +564,7 @@ void BufferLayerConsumer::onSidebandStreamChanged() { listener = mContentsChangedListener.promote(); } - if (listener != NULL) { + if (listener != nullptr) { listener->onSidebandStreamChanged(); } } diff --git a/services/surfaceflinger/BufferLayerConsumer.h b/services/surfaceflinger/BufferLayerConsumer.h index 51c2b414d7..f473390ea7 100644 --- a/services/surfaceflinger/BufferLayerConsumer.h +++ b/services/surfaceflinger/BufferLayerConsumer.h @@ -228,7 +228,7 @@ private: const sp& graphicBuffer() { return mGraphicBuffer; } const native_handle* graphicBufferHandle() { - return mGraphicBuffer == NULL ? NULL : mGraphicBuffer->handle; + return mGraphicBuffer == nullptr ? nullptr : mGraphicBuffer->handle; } const RE::Image& image() const { return mImage; } @@ -265,7 +265,7 @@ private: // computeCurrentTransformMatrixLocked computes the transform matrix for the // current texture. It uses mCurrentTransform and the current GraphicBuffer // to compute this matrix and stores it in mCurrentTransformMatrix. - // mCurrentTextureImage must not be NULL. + // mCurrentTextureImage must not be nullptr. void computeCurrentTransformMatrixLocked(); // doFenceWaitLocked inserts a wait command into the RenderEngine command diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp index ea6541a734..a69940a42e 100644 --- a/services/surfaceflinger/Client.cpp +++ b/services/surfaceflinger/Client.cpp @@ -206,7 +206,7 @@ status_t Client::destroySurface(const sp& handle) { status_t Client::clearLayerFrameStats(const sp& handle) const { sp layer = getLayerUser(handle); - if (layer == NULL) { + if (layer == nullptr) { return NAME_NOT_FOUND; } layer->clearFrameStats(); @@ -215,7 +215,7 @@ status_t Client::clearLayerFrameStats(const sp& handle) const { status_t Client::getLayerFrameStats(const sp& handle, FrameStats* outStats) const { sp layer = getLayerUser(handle); - if (layer == NULL) { + if (layer == nullptr) { return NAME_NOT_FOUND; } layer->getFrameStats(outStats); diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp index 2753f11097..9772f9a1be 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -160,7 +160,7 @@ void DisplayDevice::disconnect(HWComposer& hwc) { } bool DisplayDevice::isValid() const { - return mFlinger != NULL; + return mFlinger != nullptr; } int DisplayDevice::getWidth() const { diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h index 4186b7aac4..eaa54553ed 100644 --- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h +++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h @@ -80,7 +80,7 @@ private: // on/off. android_dataspace mDataSpace; - // mCurrentBuffer is the current buffer or NULL to indicate that there is + // mCurrentBuffer is the current buffer or nullptr to indicate that there is // no current buffer. sp mCurrentBuffer; diff --git a/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h b/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h index 4bc63bbac8..fe7944f635 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h +++ b/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h @@ -190,7 +190,7 @@ public: virtual status_t setLayer(size_t index) = 0; virtual HWCLayer* dup() = 0; static HWCLayer* copy(HWCLayer *rhs) { - return rhs ? rhs->dup() : NULL; + return rhs ? rhs->dup() : nullptr; } protected: virtual ~HWCLayer() { } @@ -205,7 +205,7 @@ public: HWCLayer* const mLayerList; size_t mIndex; - LayerListIterator() : mLayerList(NULL), mIndex(0) { } + LayerListIterator() : mLayerList(nullptr), mIndex(0) { } LayerListIterator(HWCLayer* layer, size_t index) : mLayerList(layer), mIndex(index) { } @@ -371,8 +371,8 @@ private: sp mFlinger; framebuffer_device_t* mFbDev; struct hwc_composer_device_1* mHwc; - // invariant: mLists[0] != NULL iff mHwc != NULL - // mLists[i>0] can be NULL. that display is to be ignored + // invariant: mLists[0] != nullptr iff mHwc != nullptr + // mLists[i>0] can be nullptr. that display is to be ignored struct hwc_display_contents_1* mLists[MAX_HWC_DISPLAYS]; DisplayData mDisplayData[MAX_HWC_DISPLAYS]; // protect mDisplayData from races between prepare and dump diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp index cde96e4162..3480b24390 100644 --- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp +++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp @@ -108,7 +108,7 @@ VirtualDisplaySurface::VirtualDisplaySurface(HWComposer& hwc, int32_t dispId, mConsumer->setDefaultBufferSize(sinkWidth, sinkHeight); sink->setAsyncMode(true); IGraphicBufferProducer::QueueBufferOutput output; - mSource[SOURCE_SCRATCH]->connect(NULL, NATIVE_WINDOW_API_EGL, false, &output); + mSource[SOURCE_SCRATCH]->connect(nullptr, NATIVE_WINDOW_API_EGL, false, &output); } VirtualDisplaySurface::~VirtualDisplaySurface() { @@ -203,7 +203,7 @@ status_t VirtualDisplaySurface::advanceFrame() { } sp fbBuffer = mFbProducerSlot >= 0 ? - mProducerBuffers[mFbProducerSlot] : sp(NULL); + mProducerBuffers[mFbProducerSlot] : sp(nullptr); sp outBuffer = mProducerBuffers[mOutputProducerSlot]; VDS_LOGV("advanceFrame: fb=%d(%p) out=%d(%p)", mFbProducerSlot, fbBuffer.get(), @@ -214,7 +214,7 @@ status_t VirtualDisplaySurface::advanceFrame() { mHwc.setOutputBuffer(mDisplayId, mOutputFence, outBuffer); status_t result = NO_ERROR; - if (fbBuffer != NULL) { + if (fbBuffer != nullptr) { uint32_t hwcSlot = 0; sp hwcBuffer; mHwcBufferCache.getHwcBuffer(mFbProducerSlot, fbBuffer, diff --git a/services/surfaceflinger/EventThread.cpp b/services/surfaceflinger/EventThread.cpp index a1a042039c..5c0e3b37f3 100644 --- a/services/surfaceflinger/EventThread.cpp +++ b/services/surfaceflinger/EventThread.cpp @@ -216,7 +216,7 @@ Vector< sp > EventThread::waitForEvent( size_t count = mDisplayEventConnections.size(); for (size_t i=0 ; i connection(mDisplayEventConnections[i].promote()); - if (connection != NULL) { + if (connection != nullptr) { bool added = false; if (connection->count >= 0) { // we need vsync events because at least @@ -346,7 +346,7 @@ void EventThread::dump(String8& result) const { sp connection = mDisplayEventConnections.itemAt(i).promote(); result.appendFormat(" %p: count=%d\n", - connection.get(), connection!=NULL ? connection->count : 0); + connection.get(), connection != nullptr ? connection->count : 0); } } diff --git a/services/surfaceflinger/FrameTracker.cpp b/services/surfaceflinger/FrameTracker.cpp index 99c4daaba5..1539873aaa 100644 --- a/services/surfaceflinger/FrameTracker.cpp +++ b/services/surfaceflinger/FrameTracker.cpp @@ -82,17 +82,17 @@ void FrameTracker::advanceFrame() { mFrameRecords[mOffset].frameReadyTime = INT64_MAX; mFrameRecords[mOffset].actualPresentTime = INT64_MAX; - if (mFrameRecords[mOffset].frameReadyFence != NULL) { + if (mFrameRecords[mOffset].frameReadyFence != nullptr) { // We're clobbering an unsignaled fence, so we need to decrement the // fence count. - mFrameRecords[mOffset].frameReadyFence = NULL; + mFrameRecords[mOffset].frameReadyFence = nullptr; mNumFences--; } - if (mFrameRecords[mOffset].actualPresentFence != NULL) { + if (mFrameRecords[mOffset].actualPresentFence != nullptr) { // We're clobbering an unsignaled fence, so we need to decrement the // fence count. - mFrameRecords[mOffset].actualPresentFence = NULL; + mFrameRecords[mOffset].actualPresentFence = nullptr; mNumFences--; } } @@ -153,10 +153,10 @@ void FrameTracker::processFencesLocked() const { bool updated = false; const std::shared_ptr& rfence = records[idx].frameReadyFence; - if (rfence != NULL) { + if (rfence != nullptr) { records[idx].frameReadyTime = rfence->getSignalTime(); if (records[idx].frameReadyTime < INT64_MAX) { - records[idx].frameReadyFence = NULL; + records[idx].frameReadyFence = nullptr; numFences--; updated = true; } @@ -164,10 +164,10 @@ void FrameTracker::processFencesLocked() const { const std::shared_ptr& pfence = records[idx].actualPresentFence; - if (pfence != NULL) { + if (pfence != nullptr) { records[idx].actualPresentTime = pfence->getSignalTime(); if (records[idx].actualPresentTime < INT64_MAX) { - records[idx].actualPresentFence = NULL; + records[idx].actualPresentFence = nullptr; numFences--; updated = true; } diff --git a/services/surfaceflinger/FrameTracker.h b/services/surfaceflinger/FrameTracker.h index adcdfb528d..b4a9fd68fb 100644 --- a/services/surfaceflinger/FrameTracker.h +++ b/services/surfaceflinger/FrameTracker.h @@ -35,7 +35,7 @@ class String8; // possible. // // Some of the time values tracked may be set either as a specific timestamp -// or a fence. When a non-NULL fence is set for a given time value, the +// or a fence. When a non-nullptr fence is set for a given time value, the // signal time of that fence is used instead of the timestamp. class FrameTracker { diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index cc675c491b..63f6781f02 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -265,7 +265,7 @@ Rect Layer::getContentCrop() const { if (!mCurrentCrop.isEmpty()) { // if the buffer crop is defined, we use that crop = mCurrentCrop; - } else if (getBE().compositionInfo.mBuffer != NULL) { + } else if (getBE().compositionInfo.mBuffer != nullptr) { // otherwise we use the whole buffer crop = getBE().compositionInfo.mBuffer->getBounds(); } else { diff --git a/services/surfaceflinger/LayerRejecter.cpp b/services/surfaceflinger/LayerRejecter.cpp index e8646076a5..a5f0b9878c 100644 --- a/services/surfaceflinger/LayerRejecter.cpp +++ b/services/surfaceflinger/LayerRejecter.cpp @@ -41,7 +41,7 @@ LayerRejecter::LayerRejecter(Layer::State& front, mFreezeGeometryUpdates(freezePositionUpdates) {} bool LayerRejecter::reject(const sp& buf, const BufferItem& item) { - if (buf == NULL) { + if (buf == nullptr) { return false; } diff --git a/services/surfaceflinger/RenderEngine/Program.cpp b/services/surfaceflinger/RenderEngine/Program.cpp index baf92ebf60..225bcf0327 100644 --- a/services/surfaceflinger/RenderEngine/Program.cpp +++ b/services/surfaceflinger/RenderEngine/Program.cpp @@ -115,7 +115,7 @@ String8& Program::dumpShader(String8& result, GLenum /*type*/) { GLint l; glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &l); char* src = new char[l]; - glGetShaderSource(shader, l, NULL, src); + glGetShaderSource(shader, l, nullptr, src); result.append(src); delete[] src; return result; diff --git a/services/surfaceflinger/RenderEngine/ProgramCache.cpp b/services/surfaceflinger/RenderEngine/ProgramCache.cpp index 4f138dc14c..3b8ac0e58c 100644 --- a/services/surfaceflinger/RenderEngine/ProgramCache.cpp +++ b/services/surfaceflinger/RenderEngine/ProgramCache.cpp @@ -98,7 +98,7 @@ void ProgramCache::primeCache() { continue; } Program* program = mCache.valueFor(shaderKey); - if (program == NULL) { + if (program == nullptr) { program = generateProgram(shaderKey); mCache.add(shaderKey, program); shaderCount++; @@ -273,7 +273,7 @@ void ProgramCache::useProgram(const Description& description) { // look-up the program in the cache Program* program = mCache.valueFor(needs); - if (program == NULL) { + if (program == nullptr) { // we didn't find our program, so generate one... nsecs_t time = -systemTime(); program = generateProgram(needs); diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.cpp b/services/surfaceflinger/RenderEngine/RenderEngine.cpp index 314333f044..179b79003c 100644 --- a/services/surfaceflinger/RenderEngine/RenderEngine.cpp +++ b/services/surfaceflinger/RenderEngine/RenderEngine.cpp @@ -36,11 +36,11 @@ namespace android { std::unique_ptr RenderEngine::create(int hwcFormat, uint32_t featureFlags) { // initialize EGL for the default display EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); - if (!eglInitialize(display, NULL, NULL)) { + if (!eglInitialize(display, nullptr, nullptr)) { LOG_ALWAYS_FATAL("failed to initialize EGL"); } - GLExtensions& extensions(GLExtensions::getInstance()); + GLExtensions& extensions = GLExtensions::getInstance(); extensions.initWithEGLStrings(eglQueryStringImplementationANDROID(display, EGL_VERSION), eglQueryStringImplementationANDROID(display, EGL_EXTENSIONS)); @@ -79,7 +79,7 @@ std::unique_ptr RenderEngine::create(int hwcFormat, uint32_t featu contextAttributes.push_back(EGL_NONE); contextAttributes.push_back(EGL_NONE); - EGLContext ctxt = eglCreateContext(display, config, NULL, contextAttributes.data()); + EGLContext ctxt = eglCreateContext(display, config, nullptr, contextAttributes.data()); // if can't create a GL context, we can only abort. LOG_ALWAYS_FATAL_IF(ctxt == EGL_NO_CONTEXT, "EGLContext creation failed"); @@ -132,7 +132,7 @@ std::unique_ptr RenderEngine::create(int hwcFormat, uint32_t featu } RenderEngine::RenderEngine() - : mEGLDisplay(EGL_NO_DISPLAY), mEGLConfig(NULL), mEGLContext(EGL_NO_CONTEXT) {} + : mEGLDisplay(EGL_NO_DISPLAY), mEGLConfig(nullptr), mEGLContext(EGL_NO_CONTEXT) {} RenderEngine::~RenderEngine() { eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); @@ -183,7 +183,7 @@ base::unique_fd RenderEngine::flush() { return base::unique_fd(); } - EGLSyncKHR sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL); + EGLSyncKHR sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr); if (sync == EGL_NO_SYNC_KHR) { ALOGW("failed to create EGL native fence sync: %#x", eglGetError()); return base::unique_fd(); @@ -208,7 +208,7 @@ bool RenderEngine::finish() { return false; } - EGLSyncKHR sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, NULL); + EGLSyncKHR sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, nullptr); if (sync == EGL_NO_SYNC_KHR) { ALOGW("failed to create EGL fence sync: %#x", eglGetError()); return false; @@ -347,7 +347,7 @@ void RenderEngine::readPixels(size_t l, size_t b, size_t w, size_t h, uint32_t* } void RenderEngine::dump(String8& result) { - const GLExtensions& extensions(GLExtensions::getInstance()); + const GLExtensions& extensions = GLExtensions::getInstance(); result.appendFormat("EGL implementation : %s\n", extensions.getEGLVersion()); result.appendFormat("%s\n", extensions.getEGLExtensions()); @@ -363,7 +363,7 @@ RenderEngine::BindNativeBufferAsFramebuffer::BindNativeBufferAsFramebuffer( RenderEngine& engine, ANativeWindowBuffer* buffer) : mEngine(engine) { mImage = eglCreateImageKHR(mEngine.mEGLDisplay, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, - buffer, NULL); + buffer, nullptr); if (mImage == EGL_NO_IMAGE_KHR) { mStatus = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; return; @@ -394,7 +394,7 @@ status_t RenderEngine::BindNativeBufferAsFramebuffer::getStatus() const { static status_t selectConfigForAttribute(EGLDisplay dpy, EGLint const* attrs, EGLint attribute, EGLint wanted, EGLConfig* outConfig) { EGLint numConfigs = -1, n = 0; - eglGetConfigs(dpy, NULL, 0, &numConfigs); + eglGetConfigs(dpy, nullptr, 0, &numConfigs); EGLConfig* const configs = new EGLConfig[numConfigs]; eglChooseConfig(dpy, attrs, configs, numConfigs, &n); diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index db13b99dcc..0210592c81 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -382,7 +382,7 @@ void SurfaceFlinger::createBuiltinDisplayLocked(DisplayDevice::DisplayType type) sp SurfaceFlinger::getBuiltInDisplay(int32_t id) { if (uint32_t(id) >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id); - return NULL; + return nullptr; } return mBuiltinDisplays[id]; } @@ -531,7 +531,7 @@ private: } } - if (callback != NULL) { + if (callback != nullptr) { callback->onVSyncEvent(when); } } @@ -737,7 +737,7 @@ status_t SurfaceFlinger::getSupportedFrameTimestamps( status_t SurfaceFlinger::getDisplayConfigs(const sp& display, Vector* configs) { - if ((configs == NULL) || (display.get() == NULL)) { + if (configs == nullptr || display.get() == nullptr) { return BAD_VALUE; } @@ -761,7 +761,7 @@ status_t SurfaceFlinger::getDisplayConfigs(const sp& display, static int getDensityFromProperty(char const* propName) { char property[PROPERTY_VALUE_MAX]; int density = 0; - if (property_get(propName, property, NULL) > 0) { + if (property_get(propName, property, nullptr) > 0) { density = atoi(property); } return density; @@ -842,7 +842,7 @@ status_t SurfaceFlinger::getDisplayConfigs(const sp& display, status_t SurfaceFlinger::getDisplayStats(const sp& /* display */, DisplayStatInfo* stats) { - if (stats == NULL) { + if (stats == nullptr) { return BAD_VALUE; } @@ -854,13 +854,13 @@ status_t SurfaceFlinger::getDisplayStats(const sp& /* display */, } int SurfaceFlinger::getActiveConfig(const sp& display) { - if (display == NULL) { - ALOGE("%s : display is NULL", __func__); + if (display == nullptr) { + ALOGE("%s : display is nullptr", __func__); return BAD_VALUE; } sp device(getDisplayDevice(display)); - if (device != NULL) { + if (device != nullptr) { return device->getActiveConfig(); } @@ -905,7 +905,7 @@ status_t SurfaceFlinger::setActiveConfig(const sp& display, int mode) { return true; } sp hw(mFlinger.getDisplayDevice(mDisplay)); - if (hw == NULL) { + if (hw == nullptr) { ALOGE("Attempt to set active config = %d for null display %p", mMode, mDisplay.get()); } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) { @@ -2165,7 +2165,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) const sp defaultDisplay(getDefaultDisplayDeviceLocked()); defaultDisplay->makeCurrent(); sp hw(getDisplayDeviceLocked(draw.keyAt(i))); - if (hw != NULL) + if (hw != nullptr) hw->disconnect(getHwComposer()); if (draw[i].type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) mEventThread->onHotplugReceived(draw[i].type, false); @@ -2185,7 +2185,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) // from the drawing state, so that it get re-added // below. sp hw(getDisplayDeviceLocked(display)); - if (hw != NULL) + if (hw != nullptr) hw->disconnect(getHwComposer()); mDisplays.removeItem(display); mDrawingState.displays.removeItemsAt(i); @@ -2195,7 +2195,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) } const sp disp(getDisplayDeviceLocked(display)); - if (disp != NULL) { + if (disp != nullptr) { if (state.layerStack != draw[i].layerStack) { disp->setLayerStack(state.layerStack); } @@ -2231,7 +2231,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) // Virtual displays without a surface are dormant: // they have external state (layer stack, projection, // etc.) but no internal state (i.e. a DisplayDevice). - if (state.surface != NULL) { + if (state.surface != nullptr) { // Allow VR composer to use virtual displays. if (mUseHwcVirtualDisplays || getBE().mHwc->isUsingVrComposer()) { @@ -2268,7 +2268,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) producer = vds; } } else { - ALOGE_IF(state.surface!=NULL, + ALOGE_IF(state.surface != nullptr, "adding a supported display, but rendering " "surface is provided (%p), ignoring it", state.surface.get()); @@ -2279,7 +2279,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) } const wp& display(curr.keyAt(i)); - if (dispSurface != NULL) { + if (dispSurface != nullptr) { sp hw = new DisplayDevice(this, state.type, hwcId, state.isSecure, display, dispSurface, producer, hasWideColorDisplay); @@ -2334,10 +2334,10 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) for (size_t dpy=0 ; dpy hw(mDisplays[dpy]); if (layer->belongsToDisplay(hw->getLayerStack(), hw->isPrimary())) { - if (disp == NULL) { + if (disp == nullptr) { disp = std::move(hw); } else { - disp = NULL; + disp = nullptr; break; } } @@ -2345,7 +2345,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) } if (transactionFlags & eDisplayTransactionNeeded) { - if (disp == NULL) { + if (disp == nullptr) { // NOTE: TEMPORARY FIX ONLY. Real fix should cause layers to // redraw after transform hint changes. See bug 8508397. @@ -2941,16 +2941,16 @@ void SurfaceFlinger::setTransactionState( for (size_t i=0 ; i binder = IInterface::asBinder(s.client); - if (binder != NULL) { - if (binder->queryLocalInterface(ISurfaceComposerClient::descriptor) != NULL) { + if (binder != nullptr) { + if (binder->queryLocalInterface(ISurfaceComposerClient::descriptor) != nullptr) { sp client( static_cast(s.client.get()) ); transactionFlags |= setClientStateLocked(client, s.state); } @@ -3324,7 +3324,7 @@ status_t SurfaceFlinger::onLayerRemoved(const sp& client, const sp l(client->getLayerUser(handle)); - if (l != NULL) { + if (l != nullptr) { mInterceptor.saveSurfaceDeletion(l); err = removeLayer(l); ALOGE_IF(err<0 && err != NAME_NOT_FOUND, @@ -3489,7 +3489,7 @@ void SurfaceFlinger::setPowerMode(const sp& display, int mode) { mDisplay(disp) { mMode = mode; } virtual bool handler() { sp hw(mFlinger.getDisplayDevice(mDisplay)); - if (hw == NULL) { + if (hw == nullptr) { ALOGE("Attempt to set power mode = %d for null display %p", mMode, mDisplay.get()); } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) { @@ -3978,7 +3978,7 @@ SurfaceFlinger::getLayerSortedByZForHwcDisplay(int id) { break; } } - if (dpy == NULL) { + if (dpy == nullptr) { ALOGE("getLayerSortedByZForHwcDisplay: invalid hwc display id %d", id); // Just use the primary display so we have something to return dpy = getBuiltInDisplay(DisplayDevice::DISPLAY_PRIMARY); diff --git a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp index ed806b87f5..de78c3f355 100644 --- a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp +++ b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp @@ -148,7 +148,7 @@ protected: mBGSurfaceControl = mComposerClient->createSurface( String8("BG Interceptor Test Surface"), displayWidth, displayHeight, PIXEL_FORMAT_RGBA_8888, 0); - ASSERT_TRUE(mBGSurfaceControl != NULL); + ASSERT_TRUE(mBGSurfaceControl != nullptr); ASSERT_TRUE(mBGSurfaceControl->isValid()); mBGLayerId = getSurfaceId("BG Interceptor Test Surface"); diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp index ff81dc9461..ac8a2ad868 100644 --- a/services/surfaceflinger/tests/Transaction_test.cpp +++ b/services/surfaceflinger/tests/Transaction_test.cpp @@ -148,8 +148,8 @@ static void fillSurfaceRGBA8(const sp& sc, uint8_t r, uint8_t g, bool unlock = true) { ANativeWindow_Buffer outBuffer; sp s = sc->getSurface(); - ASSERT_TRUE(s != NULL); - ASSERT_EQ(NO_ERROR, s->lock(&outBuffer, NULL)); + ASSERT_TRUE(s != nullptr); + ASSERT_EQ(NO_ERROR, s->lock(&outBuffer, nullptr)); uint8_t* img = reinterpret_cast(outBuffer.bits); for (int y = 0; y < outBuffer.height; y++) { for (int x = 0; x < outBuffer.width; x++) { @@ -279,7 +279,7 @@ public: private: sp mOutBuffer; - uint8_t* mPixels = NULL; + uint8_t* mPixels = nullptr; }; class LayerTransactionTest : public ::testing::Test { @@ -1483,14 +1483,14 @@ protected: mBGSurfaceControl = mComposerClient->createSurface(String8("BG Test Surface"), displayWidth, displayHeight, PIXEL_FORMAT_RGBA_8888, 0); - ASSERT_TRUE(mBGSurfaceControl != NULL); + ASSERT_TRUE(mBGSurfaceControl != nullptr); ASSERT_TRUE(mBGSurfaceControl->isValid()); fillSurfaceRGBA8(mBGSurfaceControl, 63, 63, 195); // Foreground surface mFGSurfaceControl = mComposerClient->createSurface(String8("FG Test Surface"), 64, 64, PIXEL_FORMAT_RGBA_8888, 0); - ASSERT_TRUE(mFGSurfaceControl != NULL); + ASSERT_TRUE(mFGSurfaceControl != nullptr); ASSERT_TRUE(mFGSurfaceControl->isValid()); fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63); @@ -1498,7 +1498,7 @@ protected: // Synchronization surface mSyncSurfaceControl = mComposerClient->createSurface(String8("Sync Test Surface"), 1, 1, PIXEL_FORMAT_RGBA_8888, 0); - ASSERT_TRUE(mSyncSurfaceControl != NULL); + ASSERT_TRUE(mSyncSurfaceControl != nullptr); ASSERT_TRUE(mSyncSurfaceControl->isValid()); fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31); @@ -2018,7 +2018,7 @@ TEST_F(ChildLayerTest, DetachChildrenDifferentClient) { mNewComposerClient->createSurface(String8("New Child Test Surface"), 10, 10, PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get()); - ASSERT_TRUE(mChildNewClient != NULL); + ASSERT_TRUE(mChildNewClient != nullptr); ASSERT_TRUE(mChildNewClient->isValid()); fillSurfaceRGBA8(mChildNewClient, 200, 200, 200); @@ -2210,7 +2210,7 @@ TEST_F(ChildLayerTest, ReparentToNoParent) { TEST_F(ChildLayerTest, ReparentFromNoParent) { sp newSurface = mComposerClient->createSurface(String8("New Surface"), 10, 10, PIXEL_FORMAT_RGBA_8888, 0); - ASSERT_TRUE(newSurface != NULL); + ASSERT_TRUE(newSurface != nullptr); ASSERT_TRUE(newSurface->isValid()); fillSurfaceRGBA8(newSurface, 63, 195, 63); -- cgit v1.2.3-59-g8ed1b From 5c6e46353676b4fd647317fde28c413d8ffe3565 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Thu, 11 Jan 2018 08:54:38 -0800 Subject: surfaceflinger: always advertise HDR10 when wide color is available For HWC that already adversises HDR10 support, this has no effect. Otherwise, SurfaceFlinger will insert HDR10 into HdrCapabilities when wide color is supported. SurfaceFlinger simulates HDR10 support by switching the color mode to DISPLAY_P3 and forcing client composition for HDR10 layers. It also has a special path to treat RGBA_1010102/BT2020_PQ as Y410/BT2020_PQ in RenderEngine when the buffer is from media. Test: manual Change-Id: Ib5f18e0100f5610ee65218108bdb9843baccbe98 --- libs/gui/BufferItem.cpp | 6 +++- libs/gui/BufferQueueProducer.cpp | 1 + libs/gui/include/gui/BufferItem.h | 3 ++ services/surfaceflinger/BufferLayer.cpp | 9 ++++++ services/surfaceflinger/BufferLayerConsumer.cpp | 7 +++++ services/surfaceflinger/BufferLayerConsumer.h | 5 ++++ services/surfaceflinger/DisplayDevice.cpp | 5 +++- services/surfaceflinger/DisplayDevice.h | 4 ++- services/surfaceflinger/SurfaceFlinger.cpp | 39 ++++++++++++++++++++++--- services/surfaceflinger/SurfaceFlinger.h | 3 +- 10 files changed, 74 insertions(+), 8 deletions(-) (limited to 'services/surfaceflinger/BufferLayer.cpp') diff --git a/libs/gui/BufferItem.cpp b/libs/gui/BufferItem.cpp index f7409dc344..f50379b3ed 100644 --- a/libs/gui/BufferItem.cpp +++ b/libs/gui/BufferItem.cpp @@ -55,7 +55,8 @@ BufferItem::BufferItem() : mSurfaceDamage(), mAutoRefresh(false), mQueuedBuffer(true), - mIsStale(false) { + mIsStale(false), + mApi(0) { } BufferItem::~BufferItem() {} @@ -84,6 +85,7 @@ size_t BufferItem::getPodSize() const { addAligned(size, mAutoRefresh); addAligned(size, mQueuedBuffer); addAligned(size, mIsStale); + addAligned(size, mApi); return size; } @@ -177,6 +179,7 @@ status_t BufferItem::flatten( writeAligned(buffer, size, mAutoRefresh); writeAligned(buffer, size, mQueuedBuffer); writeAligned(buffer, size, mIsStale); + writeAligned(buffer, size, mApi); return NO_ERROR; } @@ -247,6 +250,7 @@ status_t BufferItem::unflatten( readAligned(buffer, size, mAutoRefresh); readAligned(buffer, size, mQueuedBuffer); readAligned(buffer, size, mIsStale); + readAligned(buffer, size, mApi); return NO_ERROR; } diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp index add857c350..e583b40632 100644 --- a/libs/gui/BufferQueueProducer.cpp +++ b/libs/gui/BufferQueueProducer.cpp @@ -878,6 +878,7 @@ status_t BufferQueueProducer::queueBuffer(int slot, item.mSurfaceDamage = surfaceDamage; item.mQueuedBuffer = true; item.mAutoRefresh = mCore->mSharedBufferMode && mCore->mAutoRefresh; + item.mApi = mCore->mConnectedApi; mStickyTransform = stickyTransform; diff --git a/libs/gui/include/gui/BufferItem.h b/libs/gui/include/gui/BufferItem.h index 7740b9f095..218bb424fb 100644 --- a/libs/gui/include/gui/BufferItem.h +++ b/libs/gui/include/gui/BufferItem.h @@ -127,6 +127,9 @@ class BufferItem : public Flattenable { // Indicates that this BufferItem contains a stale buffer which has already // been released by the BufferQueue. bool mIsStale; + + // Indicates the API (NATIVE_WINDOW_API_xxx) that queues the buffer. + int mApi; }; } // namespace android diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index d860f58509..ab6a559aad 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -821,8 +821,17 @@ void BufferLayer::drawWithOpenGL(const RenderArea& renderArea, bool useIdentityT engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), false /* disableTexture */, getColor()); engine.setSourceDataSpace(mCurrentState.dataSpace); + + if (mCurrentState.dataSpace == HAL_DATASPACE_BT2020_PQ && + mConsumer->getCurrentApi() == NATIVE_WINDOW_API_MEDIA && + getBE().compositionInfo.mBuffer->getPixelFormat() == HAL_PIXEL_FORMAT_RGBA_1010102) { + engine.setSourceY410BT2020(true); + } + engine.drawMesh(getBE().mMesh); engine.disableBlending(); + + engine.setSourceY410BT2020(false); } uint32_t BufferLayer::getProducerStickyTransform() const { diff --git a/services/surfaceflinger/BufferLayerConsumer.cpp b/services/surfaceflinger/BufferLayerConsumer.cpp index 8f5c9c740b..4d9b43f52e 100644 --- a/services/surfaceflinger/BufferLayerConsumer.cpp +++ b/services/surfaceflinger/BufferLayerConsumer.cpp @@ -68,6 +68,7 @@ BufferLayerConsumer::BufferLayerConsumer(const sp& bq, R mCurrentFrameNumber(0), mCurrentTransformToDisplayInverse(false), mCurrentSurfaceDamage(), + mCurrentApi(0), mDefaultWidth(1), mDefaultHeight(1), mFilteringEnabled(true), @@ -346,6 +347,7 @@ status_t BufferLayerConsumer::updateAndReleaseLocked(const BufferItem& item, mCurrentFrameNumber = item.mFrameNumber; mCurrentTransformToDisplayInverse = item.mTransformToDisplayInverse; mCurrentSurfaceDamage = item.mSurfaceDamage; + mCurrentApi = item.mApi; computeCurrentTransformMatrixLocked(); @@ -469,6 +471,11 @@ const Region& BufferLayerConsumer::getSurfaceDamage() const { return mCurrentSurfaceDamage; } +int BufferLayerConsumer::getCurrentApi() const { + Mutex::Autolock lock(mMutex); + return mCurrentApi; +} + sp BufferLayerConsumer::getCurrentBuffer(int* outSlot) const { Mutex::Autolock lock(mMutex); diff --git a/services/surfaceflinger/BufferLayerConsumer.h b/services/surfaceflinger/BufferLayerConsumer.h index f473390ea7..a0272b3622 100644 --- a/services/surfaceflinger/BufferLayerConsumer.h +++ b/services/surfaceflinger/BufferLayerConsumer.h @@ -138,6 +138,9 @@ public: // must be called from SF main thread const Region& getSurfaceDamage() const; + // getCurrentApi retrieves the API which queues the current buffer. + int getCurrentApi() const; + // See GLConsumer::setDefaultBufferSize. status_t setDefaultBufferSize(uint32_t width, uint32_t height); @@ -337,6 +340,8 @@ private: // The portion of this surface that has changed since the previous frame Region mCurrentSurfaceDamage; + int mCurrentApi; + uint32_t mDefaultWidth, mDefaultHeight; // mFilteringEnabled indicates whether the transform matrix is computed for diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp index d121a86ead..cf70529b53 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -76,7 +76,8 @@ DisplayDevice::DisplayDevice( const wp& displayToken, const sp& displaySurface, const sp& producer, - bool supportWideColor) + bool supportWideColor, + bool supportHdr) : lastCompositionHadVisibleLayers(false), mFlinger(flinger), mType(type), @@ -100,6 +101,8 @@ DisplayDevice::DisplayDevice( mActiveColorMode = HAL_COLOR_MODE_NATIVE; mDisplayHasWideColor = supportWideColor; + mDisplayHasHdr = supportHdr; + /* * Create our display's surface */ diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h index 499bf8e6a0..a4706701a8 100644 --- a/services/surfaceflinger/DisplayDevice.h +++ b/services/surfaceflinger/DisplayDevice.h @@ -78,7 +78,7 @@ public: const wp& displayToken, const sp& displaySurface, const sp& producer, - bool supportWideColor); + bool supportWideColor, bool supportHdr); // clang-format on ~DisplayDevice(); @@ -128,6 +128,7 @@ public: status_t beginFrame(bool mustRecompose) const; status_t prepareFrame(HWComposer& hwc); bool getWideColorSupport() const { return mDisplayHasWideColor; } + bool getHdrSupport() const { return mDisplayHasHdr; } void swapBuffers(HWComposer& hwc) const; @@ -235,6 +236,7 @@ private: // Initialized by SurfaceFlinger when the DisplayDevice is created. // Fed to RenderEngine during composition. bool mDisplayHasWideColor; + bool mDisplayHasHdr; }; struct DisplayDeviceState { diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index a91525d8d0..974a261278 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -1041,7 +1041,19 @@ status_t SurfaceFlinger::getHdrCapabilities(const sp& display, std::unique_ptr capabilities = getBE().mHwc->getHdrCapabilities(displayDevice->getHwcDisplayId()); if (capabilities) { - std::swap(*outCapabilities, *capabilities); + if (displayDevice->getWideColorSupport() && !displayDevice->getHdrSupport()) { + // insert HDR10 as we will force client composition for HDR10 + // layers + std::vector types = capabilities->getSupportedHdrTypes(); + types.push_back(HAL_HDR_HDR10); + + *outCapabilities = HdrCapabilities(types, + capabilities->getDesiredMaxLuminance(), + capabilities->getDesiredMaxAverageLuminance(), + capabilities->getDesiredMinLuminance()); + } else { + *outCapabilities = std::move(*capabilities); + } } else { return BAD_VALUE; } @@ -1793,7 +1805,7 @@ android_color_mode SurfaceFlinger::pickColorMode(android_dataspace dataSpace) co } android_dataspace SurfaceFlinger::bestTargetDataSpace( - android_dataspace a, android_dataspace b) const { + android_dataspace a, android_dataspace b, bool hasHdr) const { // Only support sRGB and Display-P3 right now. if (a == HAL_DATASPACE_DISPLAY_P3 || b == HAL_DATASPACE_DISPLAY_P3) { return HAL_DATASPACE_DISPLAY_P3; @@ -1804,6 +1816,9 @@ android_dataspace SurfaceFlinger::bestTargetDataSpace( if (a == HAL_DATASPACE_V0_SCRGB || b == HAL_DATASPACE_V0_SCRGB) { return HAL_DATASPACE_DISPLAY_P3; } + if (!hasHdr && (a == HAL_DATASPACE_BT2020_PQ || b == HAL_DATASPACE_BT2020_PQ)) { + return HAL_DATASPACE_DISPLAY_P3; + } return HAL_DATASPACE_V0_SRGB; } @@ -1885,6 +1900,11 @@ void SurfaceFlinger::setUpHWComposer() { "display %zd: %d", displayId, result); } for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { + if (layer->getDataSpace() == HAL_DATASPACE_BT2020_PQ && + !displayDevice->getHdrSupport()) { + layer->forceClientComposition(hwcId); + } + if (layer->getForceClientComposition(hwcId)) { ALOGV("[%s] Requesting Client composition", layer->getName().string()); layer->setCompositionType(hwcId, HWC2::Composition::Client); @@ -1899,7 +1919,8 @@ void SurfaceFlinger::setUpHWComposer() { android_dataspace newDataSpace = HAL_DATASPACE_V0_SRGB; for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { - newDataSpace = bestTargetDataSpace(layer->getDataSpace(), newDataSpace); + newDataSpace = bestTargetDataSpace(layer->getDataSpace(), newDataSpace, + displayDevice->getHdrSupport()); ALOGV("layer: %s, dataspace: %s (%#x), newDataSpace: %s (%#x)", layer->getName().string(), dataspaceDetails(layer->getDataSpace()).c_str(), layer->getDataSpace(), dataspaceDetails(newDataSpace).c_str(), newDataSpace); @@ -2253,9 +2274,19 @@ void SurfaceFlinger::processDisplayChangesLocked() { useWideColorMode = hasWideColorModes && hasWideColorDisplay; } + bool hasHdrSupport = false; + std::unique_ptr hdrCapabilities = + getHwComposer().getHdrCapabilities(state.type); + if (hdrCapabilities) { + const std::vector types = hdrCapabilities->getSupportedHdrTypes(); + auto iter = std::find(types.cbegin(), types.cend(), HAL_HDR_HDR10); + hasHdrSupport = iter != types.cend(); + } + sp hw = new DisplayDevice(this, state.type, hwcId, state.isSecure, display, - dispSurface, producer, useWideColorMode); + dispSurface, producer, useWideColorMode, + hasHdrSupport); android_color_mode defaultColorMode = HAL_COLOR_MODE_NATIVE; if (useWideColorMode) { diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 4da0803f67..1349becf13 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -607,7 +607,8 @@ private: // Given a dataSpace, returns the appropriate color_mode to use // to display that dataSpace. android_color_mode pickColorMode(android_dataspace dataSpace) const; - android_dataspace bestTargetDataSpace(android_dataspace a, android_dataspace b) const; + android_dataspace bestTargetDataSpace(android_dataspace a, android_dataspace b, + bool hasHdr) const; mat4 computeSaturationMatrix() const; -- cgit v1.2.3-59-g8ed1b From 13170c80f4ddb3f4cdb2ded601e0357fca68942e Mon Sep 17 00:00:00 2001 From: Peiyong Lin Date: Mon, 22 Jan 2018 18:55:51 -0800 Subject: [SurfaceFlinger] Update ColorLayer to set dataspace. This patch sets the dataspace for ColorLayer when setPerFrameData is called. Previously, only the dataspace of BufferLayer is set. This helps clarify what color space the color value that set through SetColor API is in. BUG: 69970838 Test: None Change-Id: I10982efc996bbecbcc433d3d7b0469ab8bf4cb5e --- services/surfaceflinger/BufferLayer.cpp | 6 +++--- services/surfaceflinger/ColorLayer.cpp | 11 +++++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) (limited to 'services/surfaceflinger/BufferLayer.cpp') diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index d860f58509..2ac4ec81e2 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -622,10 +622,10 @@ void BufferLayer::setPerFrameData(const sp& displayDevice) setCompositionType(hwcId, HWC2::Composition::Device); } - ALOGV("setPerFrameData: dataspace = %d", mCurrentState.dataSpace); - error = hwcLayer->setDataspace(mCurrentState.dataSpace); + ALOGV("setPerFrameData: dataspace = %d", mDrawingState.dataSpace); + error = hwcLayer->setDataspace(mDrawingState.dataSpace); if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), mCurrentState.dataSpace, + ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), mDrawingState.dataSpace, to_string(error).c_str(), static_cast(error)); } diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp index b784c8d956..10e77903ba 100644 --- a/services/surfaceflinger/ColorLayer.cpp +++ b/services/surfaceflinger/ColorLayer.cpp @@ -69,9 +69,20 @@ void ColorLayer::setPerFrameData(const sp& displayDevice) { auto& hwcInfo = getBE().mHwcLayers[hwcId]; auto& hwcLayer = hwcInfo.layer; auto error = hwcLayer->setVisibleRegion(visible); + if (error != HWC2::Error::None) { + ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(), + to_string(error).c_str(), static_cast(error)); + visible.dump(LOG_TAG); + } setCompositionType(hwcId, HWC2::Composition::SolidColor); + error = hwcLayer->setDataspace(mDrawingState.dataSpace); + if (error != HWC2::Error::None) { + ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), mDrawingState.dataSpace, + to_string(error).c_str(), static_cast(error)); + } + half4 color = getColor(); error = hwcLayer->setColor({static_cast(std::round(255.0f * color.r)), static_cast(std::round(255.0f * color.g)), -- cgit v1.2.3-59-g8ed1b From 8d2651e484d5090e8d067672cb82ca285b93f4a9 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Wed, 24 Jan 2018 12:18:49 -0800 Subject: surfaceflinger: support BT2020_ITU_PQ Games use BT2020_PQ while videos use BT2020_ITU_PQ usually. We can support both and treat them as the same, since the YUV->RGB conversion happens before the pixel data are uploaded to texture, or happens inside the GLES driver. The only caveat is that we treat RGBA1010102/BT2020_ITU_PQ from media specially. The hack is also updated in this change. Test: manual Change-Id: I1e4b8e0d907af5e5a95cf7fde1a7ea67a4e7da0b --- services/surfaceflinger/BufferLayer.cpp | 2 +- services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp | 3 ++- services/surfaceflinger/SurfaceFlinger.cpp | 12 +++++++++--- 3 files changed, 12 insertions(+), 5 deletions(-) (limited to 'services/surfaceflinger/BufferLayer.cpp') diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index ba9eaf6db2..4d4c9fcc3d 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -822,7 +822,7 @@ void BufferLayer::drawWithOpenGL(const RenderArea& renderArea, bool useIdentityT getColor()); engine.setSourceDataSpace(mCurrentState.dataSpace); - if (mCurrentState.dataSpace == HAL_DATASPACE_BT2020_PQ && + if (mCurrentState.dataSpace == HAL_DATASPACE_BT2020_ITU_PQ && mConsumer->getCurrentApi() == NATIVE_WINDOW_API_MEDIA && getBE().compositionInfo.mBuffer->getPixelFormat() == HAL_PIXEL_FORMAT_RGBA_1010102) { engine.setSourceY410BT2020(true); diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp index 323cec75b9..5133bacc2d 100644 --- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp +++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp @@ -326,11 +326,12 @@ void GLES20RenderEngine::drawMesh(const Mesh& mesh) { if (usesWideColor()) { Description wideColorState = mState; - switch (mDataSpace) { + switch (int(mDataSpace)) { case HAL_DATASPACE_DISPLAY_P3: // input matches output break; case HAL_DATASPACE_BT2020_PQ: + case HAL_DATASPACE_BT2020_ITU_PQ: wideColorState.setColorMatrix(mState.getColorMatrix() * mBt2020ToDisplayP3); wideColorState.setInputTransferFunction(Description::TransferFunction::ST2084); wideColorState.setOutputTransferFunction(Description::TransferFunction::SRGB); diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 974a261278..d8740d973e 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -1816,8 +1816,13 @@ android_dataspace SurfaceFlinger::bestTargetDataSpace( if (a == HAL_DATASPACE_V0_SCRGB || b == HAL_DATASPACE_V0_SCRGB) { return HAL_DATASPACE_DISPLAY_P3; } - if (!hasHdr && (a == HAL_DATASPACE_BT2020_PQ || b == HAL_DATASPACE_BT2020_PQ)) { - return HAL_DATASPACE_DISPLAY_P3; + if (!hasHdr) { + if (a == HAL_DATASPACE_BT2020_PQ || b == HAL_DATASPACE_BT2020_PQ) { + return HAL_DATASPACE_DISPLAY_P3; + } + if (a == HAL_DATASPACE_BT2020_ITU_PQ || b == HAL_DATASPACE_BT2020_ITU_PQ) { + return HAL_DATASPACE_DISPLAY_P3; + } } return HAL_DATASPACE_V0_SRGB; @@ -1900,7 +1905,8 @@ void SurfaceFlinger::setUpHWComposer() { "display %zd: %d", displayId, result); } for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { - if (layer->getDataSpace() == HAL_DATASPACE_BT2020_PQ && + if ((layer->getDataSpace() == HAL_DATASPACE_BT2020_PQ || + layer->getDataSpace() == HAL_DATASPACE_BT2020_ITU_PQ) && !displayDevice->getHdrSupport()) { layer->forceClientComposition(hwcId); } -- cgit v1.2.3-59-g8ed1b From 144e116f45f196396f0d59d5fc09766ab618f885 Mon Sep 17 00:00:00 2001 From: Lloyd Pique Date: Wed, 20 Dec 2017 16:44:52 -0800 Subject: SF: Separate RenderEngine into interface and impl This allows the RenderEngine to be substituted by a GMock for tests. RE::RenderEngine is now a pure virtual interface class. RE::impl::RenderEngine is the normal/base implementation. Similarly, RE::Image and RE::Surface are pure virtual interfaces. RE::impl::Image and RE::impl::Surface are the normal implementations. Test: Builds Bug: None Change-Id: Ib5e658df4bb4efc1a9c0ae95feaf0c1e052cdc94 --- services/surfaceflinger/BufferLayer.cpp | 4 +- services/surfaceflinger/BufferLayerConsumer.cpp | 21 ++- services/surfaceflinger/BufferLayerConsumer.h | 22 ++- services/surfaceflinger/ColorLayer.cpp | 2 +- services/surfaceflinger/DisplayDevice.cpp | 30 +-- services/surfaceflinger/DisplayDevice.h | 2 +- services/surfaceflinger/Layer.cpp | 2 +- services/surfaceflinger/Layer.h | 2 +- .../RenderEngine/GLES20RenderEngine.cpp | 6 +- .../RenderEngine/GLES20RenderEngine.h | 7 +- services/surfaceflinger/RenderEngine/Image.cpp | 5 + services/surfaceflinger/RenderEngine/Image.h | 23 ++- .../surfaceflinger/RenderEngine/RenderEngine.cpp | 76 +++++--- .../surfaceflinger/RenderEngine/RenderEngine.h | 209 ++++++++++++++------- services/surfaceflinger/RenderEngine/Surface.cpp | 5 + services/surfaceflinger/RenderEngine/Surface.h | 50 +++-- services/surfaceflinger/SurfaceFlinger.cpp | 22 ++- services/surfaceflinger/SurfaceFlinger.h | 19 +- 18 files changed, 336 insertions(+), 171 deletions(-) (limited to 'services/surfaceflinger/BufferLayer.cpp') diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index 4d4c9fcc3d..3dbc136205 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -200,7 +200,7 @@ void BufferLayer::onDraw(const RenderArea& renderArea, const Region& clip, bool blackOutLayer = isProtected() || (isSecure() && !renderArea.isSecure()); - RenderEngine& engine(mFlinger->getRenderEngine()); + auto& engine(mFlinger->getRenderEngine()); if (!blackOutLayer) { // TODO: we could be more subtle with isFixedSize() @@ -817,7 +817,7 @@ void BufferLayer::drawWithOpenGL(const RenderArea& renderArea, bool useIdentityT texCoords[2] = vec2(right, 1.0f - bottom); texCoords[3] = vec2(right, 1.0f - top); - RenderEngine& engine(mFlinger->getRenderEngine()); + auto& engine(mFlinger->getRenderEngine()); engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), false /* disableTexture */, getColor()); engine.setSourceDataSpace(mCurrentState.dataSpace); diff --git a/services/surfaceflinger/BufferLayerConsumer.cpp b/services/surfaceflinger/BufferLayerConsumer.cpp index 4d9b43f52e..46ec0e322b 100644 --- a/services/surfaceflinger/BufferLayerConsumer.cpp +++ b/services/surfaceflinger/BufferLayerConsumer.cpp @@ -23,6 +23,7 @@ #include "DispSync.h" #include "Layer.h" +#include "RenderEngine/Image.h" #include "RenderEngine/RenderEngine.h" #include @@ -56,8 +57,8 @@ namespace android { static const mat4 mtxIdentity; -BufferLayerConsumer::BufferLayerConsumer(const sp& bq, RenderEngine& engine, - uint32_t tex, Layer* layer) +BufferLayerConsumer::BufferLayerConsumer(const sp& bq, + RE::RenderEngine& engine, uint32_t tex, Layer* layer) : ConsumerBase(bq, false), mCurrentCrop(Rect::EMPTY_RECT), mCurrentTransform(0), @@ -359,7 +360,7 @@ status_t BufferLayerConsumer::bindTextureImageLocked() { if (mCurrentTexture == BufferQueue::INVALID_BUFFER_SLOT && mCurrentTextureImage == nullptr) { BLC_LOGE("bindTextureImage: no currently-bound texture"); - mRE.bindExternalTextureImage(mTexName, RE::Image(mRE)); + mRE.bindExternalTextureImage(mTexName, *mRE.createImage()); return NO_INIT; } @@ -367,7 +368,7 @@ status_t BufferLayerConsumer::bindTextureImageLocked() { status_t err = mCurrentTextureImage->createIfNeeded(imageCrop); if (err != NO_ERROR) { BLC_LOGW("bindTextureImage: can't create image on slot=%d", mCurrentTexture); - mRE.bindExternalTextureImage(mTexName, RE::Image(mRE)); + mRE.bindExternalTextureImage(mTexName, *mRE.createImage()); return UNKNOWN_ERROR; } @@ -604,13 +605,15 @@ void BufferLayerConsumer::dumpLocked(String8& result, const char* prefix) const ConsumerBase::dumpLocked(result, prefix); } -BufferLayerConsumer::Image::Image(sp graphicBuffer, const RenderEngine& engine) +BufferLayerConsumer::Image::Image(sp graphicBuffer, RE::RenderEngine& engine) : mGraphicBuffer(graphicBuffer), - mImage{engine}, + mImage{engine.createImage()}, mCreated(false), mCropWidth(0), mCropHeight(0) {} +BufferLayerConsumer::Image::~Image() = default; + status_t BufferLayerConsumer::Image::createIfNeeded(const Rect& imageCrop) { const int32_t cropWidth = imageCrop.width(); const int32_t cropHeight = imageCrop.height(); @@ -618,9 +621,9 @@ status_t BufferLayerConsumer::Image::createIfNeeded(const Rect& imageCrop) { return OK; } - mCreated = mImage.setNativeWindowBuffer(mGraphicBuffer->getNativeBuffer(), - mGraphicBuffer->getUsage() & GRALLOC_USAGE_PROTECTED, - cropWidth, cropHeight); + mCreated = mImage->setNativeWindowBuffer(mGraphicBuffer->getNativeBuffer(), + mGraphicBuffer->getUsage() & GRALLOC_USAGE_PROTECTED, + cropWidth, cropHeight); if (mCreated) { mCropWidth = cropWidth; mCropHeight = cropHeight; diff --git a/services/surfaceflinger/BufferLayerConsumer.h b/services/surfaceflinger/BufferLayerConsumer.h index a0272b3622..11048d8df8 100644 --- a/services/surfaceflinger/BufferLayerConsumer.h +++ b/services/surfaceflinger/BufferLayerConsumer.h @@ -17,8 +17,6 @@ #ifndef ANDROID_BUFFERLAYERCONSUMER_H #define ANDROID_BUFFERLAYERCONSUMER_H -#include "RenderEngine/Image.h" - #include #include #include @@ -36,9 +34,13 @@ namespace android { class DispSync; class Layer; -class RenderEngine; class String8; +namespace RE { +class RenderEngine; +class Image; +} // namespace RE + /* * BufferLayerConsumer consumes buffers of graphics data from a BufferQueue, * and makes them available to RenderEngine as a texture. @@ -70,8 +72,8 @@ public: // BufferLayerConsumer constructs a new BufferLayerConsumer object. The // tex parameter indicates the name of the RenderEngine texture to which // images are to be streamed. - BufferLayerConsumer(const sp& bq, RenderEngine& engine, uint32_t tex, - Layer* layer); + BufferLayerConsumer(const sp& bq, RE::RenderEngine& engine, + uint32_t tex, Layer* layer); // Sets the contents changed listener. This should be used instead of // ConsumerBase::setFrameAvailableListener(). @@ -220,7 +222,7 @@ private: // also only creating new RE::Images from buffers when required. class Image : public LightRefBase { public: - Image(sp graphicBuffer, const RenderEngine& engine); + Image(sp graphicBuffer, RE::RenderEngine& engine); Image(const Image& rhs) = delete; Image& operator=(const Image& rhs) = delete; @@ -234,18 +236,18 @@ private: return mGraphicBuffer == nullptr ? nullptr : mGraphicBuffer->handle; } - const RE::Image& image() const { return mImage; } + const RE::Image& image() const { return *mImage; } private: // Only allow instantiation using ref counting. friend class LightRefBase; - virtual ~Image() = default; + virtual ~Image(); // mGraphicBuffer is the buffer that was used to create this image. sp mGraphicBuffer; // mImage is the image created from mGraphicBuffer. - RE::Image mImage; + std::unique_ptr mImage; bool mCreated; int32_t mCropWidth; int32_t mCropHeight; @@ -349,7 +351,7 @@ private: // setFilteringEnabled(). bool mFilteringEnabled; - RenderEngine& mRE; + RE::RenderEngine& mRE; // mTexName is the name of the RenderEngine texture to which streamed // images will be bound when bindTexImage is called. It is set at diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp index 10e77903ba..80a90a7d31 100644 --- a/services/surfaceflinger/ColorLayer.cpp +++ b/services/surfaceflinger/ColorLayer.cpp @@ -48,7 +48,7 @@ void ColorLayer::onDraw(const RenderArea& renderArea, const Region& /* clip */, if (s.color.a > 0) { Mesh mesh(Mesh::TRIANGLE_FAN, 4, 2); computeGeometry(renderArea, mesh, useIdentityTransform); - RenderEngine& engine(mFlinger->getRenderEngine()); + auto& engine(mFlinger->getRenderEngine()); engine.setupLayerBlending(getPremultipledAlpha(), false /* opaque */, true /* disableTexture */, s.color); engine.drawMesh(mesh); diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp index cf70529b53..d40666e6f1 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -84,7 +84,7 @@ DisplayDevice::DisplayDevice( mHwcDisplayId(hwcId), mDisplayToken(displayToken), mDisplaySurface(displaySurface), - mSurface{flinger->getRenderEngine()}, + mSurface{flinger->getRenderEngine().createSurface()}, mDisplayWidth(), mDisplayHeight(), mPageFlipCount(), @@ -106,11 +106,11 @@ DisplayDevice::DisplayDevice( /* * Create our display's surface */ - mSurface.setCritical(mType == DisplayDevice::DISPLAY_PRIMARY); - mSurface.setAsync(mType >= DisplayDevice::DISPLAY_VIRTUAL); - mSurface.setNativeWindow(window); - mDisplayWidth = mSurface.queryWidth(); - mDisplayHeight = mSurface.queryHeight(); + mSurface->setCritical(mType == DisplayDevice::DISPLAY_PRIMARY); + mSurface->setAsync(mType >= DisplayDevice::DISPLAY_VIRTUAL); + mSurface->setNativeWindow(window); + mDisplayWidth = mSurface->queryWidth(); + mDisplayHeight = mSurface->queryHeight(); // Make sure that composition can never be stalled by a virtual display // consumer that isn't processing buffers fast enough. We have to do this @@ -207,7 +207,7 @@ status_t DisplayDevice::prepareFrame(HWComposer& hwc) { void DisplayDevice::swapBuffers(HWComposer& hwc) const { if (hwc.hasClientComposition(mHwcDisplayId) || hwc.hasFlipClientTargetRequest(mHwcDisplayId)) { - mSurface.swapBuffers(); + mSurface->swapBuffers(); } status_t result = mDisplaySurface->advanceFrame(); @@ -222,7 +222,7 @@ void DisplayDevice::onSwapBuffersCompleted() const { } bool DisplayDevice::makeCurrent() const { - bool success = mFlinger->getRenderEngine().setCurrentSurface(mSurface); + bool success = mFlinger->getRenderEngine().setCurrentSurface(*mSurface); setViewportAndProjection(); return success; } @@ -360,14 +360,14 @@ status_t DisplayDevice::orientationToTransfrom( void DisplayDevice::setDisplaySize(const int newWidth, const int newHeight) { dirtyRegion.set(getBounds()); - mSurface.setNativeWindow(nullptr); + mSurface->setNativeWindow(nullptr); mDisplaySurface->resizeBuffers(newWidth, newHeight); ANativeWindow* const window = mNativeWindow.get(); - mSurface.setNativeWindow(window); - mDisplayWidth = mSurface.queryWidth(); - mDisplayHeight = mSurface.queryHeight(); + mSurface->setNativeWindow(window); + mDisplayWidth = mSurface->queryWidth(); + mDisplayHeight = mSurface->queryHeight(); LOG_FATAL_IF(mDisplayWidth != newWidth, "Unable to set new width to %d", newWidth); @@ -474,9 +474,9 @@ void DisplayDevice::dump(String8& result) const { "(%d:%d:%d:%d), orient=%2d (type=%08x), " "flips=%u, isSecure=%d, powerMode=%d, activeConfig=%d, numLayers=%zu\n", mType, mHwcDisplayId, mLayerStack, mDisplayWidth, mDisplayHeight, window, - mSurface.queryRedSize(), mSurface.queryGreenSize(), mSurface.queryBlueSize(), - mSurface.queryAlphaSize(), mOrientation, tr.getType(), - getPageFlipCount(), mIsSecure, mPowerMode, mActiveConfig, + mSurface->queryRedSize(), mSurface->queryGreenSize(), + mSurface->queryBlueSize(), mSurface->queryAlphaSize(), mOrientation, + tr.getType(), getPageFlipCount(), mIsSecure, mPowerMode, mActiveConfig, mVisibleLayersSortedByZ.size()); result.appendFormat(" v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d]," "transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n", diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h index a4706701a8..d5ed15fa28 100644 --- a/services/surfaceflinger/DisplayDevice.h +++ b/services/surfaceflinger/DisplayDevice.h @@ -187,7 +187,7 @@ private: sp mNativeWindow; sp mDisplaySurface; - RE::Surface mSurface; + std::unique_ptr mSurface; int mDisplayWidth; int mDisplayHeight; mutable uint32_t mPageFlipCount; diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 067a09fb5d..78dd40b32f 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -719,7 +719,7 @@ void Layer::draw(const RenderArea& renderArea) const { void Layer::clearWithOpenGL(const RenderArea& renderArea, float red, float green, float blue, float alpha) const { - RenderEngine& engine(mFlinger->getRenderEngine()); + auto& engine(mFlinger->getRenderEngine()); computeGeometry(renderArea, getBE().mMesh, false); engine.setupFillWithColor(red, green, blue, alpha); engine.drawMesh(getBE().mMesh); diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index c63399e876..3671a2bb32 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -90,7 +90,7 @@ struct CompositionInfo { hwc_color_t color; } hwc; struct { - RenderEngine* renderEngine; + RE::RenderEngine* renderEngine; Mesh* mesh; } renderEngine; }; diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp index 34d968df6b..9ecf8ce2e7 100644 --- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp +++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp @@ -105,6 +105,8 @@ void writePPM(const char* basename, GLuint width, GLuint height) { // --------------------------------------------------------------------------- namespace android { +namespace RE { +namespace impl { // --------------------------------------------------------------------------- GLES20RenderEngine::GLES20RenderEngine(uint32_t featureFlags) @@ -379,7 +381,9 @@ void GLES20RenderEngine::dump(String8& result) { } // --------------------------------------------------------------------------- -}; // namespace android +} // namespace impl +} // namespace RE +} // namespace android // --------------------------------------------------------------------------- #if defined(__gl_h_) diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h index f3af5479c6..6e86ea2680 100644 --- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h +++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h @@ -35,6 +35,9 @@ class String8; class Mesh; class Texture; +namespace RE { +namespace impl { + class GLES20RenderEngine : public RenderEngine { GLuint mProtectedTexName; GLint mMaxViewportDims[2]; @@ -105,7 +108,9 @@ protected: }; // --------------------------------------------------------------------------- -}; // namespace android +} // namespace impl +} // namespace RE +} // namespace android // --------------------------------------------------------------------------- #endif /* SF_GLES20RENDERENGINE_H_ */ diff --git a/services/surfaceflinger/RenderEngine/Image.cpp b/services/surfaceflinger/RenderEngine/Image.cpp index 1f8e75a0ae..0d06422a41 100644 --- a/services/surfaceflinger/RenderEngine/Image.cpp +++ b/services/surfaceflinger/RenderEngine/Image.cpp @@ -26,6 +26,10 @@ namespace android { namespace RE { +Image::~Image() = default; + +namespace impl { + Image::Image(const RenderEngine& engine) : mEGLDisplay(engine.getEGLDisplay()) {} Image::~Image() { @@ -83,5 +87,6 @@ bool Image::setNativeWindowBuffer(ANativeWindowBuffer* buffer, bool isProtected, return true; } +} // namespace impl } // namespace RE } // namespace android diff --git a/services/surfaceflinger/RenderEngine/Image.h b/services/surfaceflinger/RenderEngine/Image.h index f55aa59a8a..1ae7e09cba 100644 --- a/services/surfaceflinger/RenderEngine/Image.h +++ b/services/surfaceflinger/RenderEngine/Image.h @@ -24,30 +24,39 @@ struct ANativeWindowBuffer; namespace android { - -class RenderEngine; - namespace RE { class Image { public: - Image(const RenderEngine& engine); - ~Image(); + virtual ~Image() = 0; + virtual bool setNativeWindowBuffer(ANativeWindowBuffer* buffer, bool isProtected, + int32_t cropWidth, int32_t cropHeight) = 0; +}; + +namespace impl { + +class RenderEngine; + +class Image : public RE::Image { +public: + explicit Image(const RenderEngine& engine); + ~Image() override; Image(const Image&) = delete; Image& operator=(const Image&) = delete; bool setNativeWindowBuffer(ANativeWindowBuffer* buffer, bool isProtected, int32_t cropWidth, - int32_t cropHeight); + int32_t cropHeight) override; private: // methods internal to RenderEngine - friend class android::RenderEngine; + friend class RenderEngine; EGLSurface getEGLImage() const { return mEGLImage; } EGLDisplay mEGLDisplay; EGLImageKHR mEGLImage = EGL_NO_IMAGE_KHR; }; +} // namespace impl } // namespace RE } // namespace android diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.cpp b/services/surfaceflinger/RenderEngine/RenderEngine.cpp index 22016edd85..4c878aee31 100644 --- a/services/surfaceflinger/RenderEngine/RenderEngine.cpp +++ b/services/surfaceflinger/RenderEngine/RenderEngine.cpp @@ -37,8 +37,13 @@ extern "C" EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy // --------------------------------------------------------------------------- namespace android { +namespace RE { // --------------------------------------------------------------------------- +RenderEngine::~RenderEngine() = default; + +namespace impl { + std::unique_ptr RenderEngine::create(int hwcFormat, uint32_t featureFlags) { // initialize EGL for the default display EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); @@ -137,9 +142,7 @@ std::unique_ptr RenderEngine::create(int hwcFormat, uint32_t featu bool RenderEngine::overrideUseContextPriorityFromConfig(bool useContextPriority) { OptionalBool ret; - ISurfaceFlingerConfigs::getService()->useContextPriority([&ret](OptionalBool b) { - ret = b; - }); + ISurfaceFlingerConfigs::getService()->useContextPriority([&ret](OptionalBool b) { ret = b; }); if (ret.specified) { return ret.value; } else { @@ -177,7 +180,22 @@ bool RenderEngine::isCurrent() const { return mEGLDisplay == eglGetCurrentDisplay() && mEGLContext == eglGetCurrentContext(); } -bool RenderEngine::setCurrentSurface(const RE::Surface& surface) { +std::unique_ptr RenderEngine::createSurface() { + return std::make_unique(*this); +} + +std::unique_ptr RenderEngine::createImage() { + return std::make_unique(*this); +} + +bool RenderEngine::setCurrentSurface(const android::RE::Surface& surface) { + // Note: RE::Surface is an abstract interface. This implementation only ever + // creates RE::impl::Surface's, so it is safe to just cast to the actual + // type. + return setCurrentSurface(static_cast(surface)); +} + +bool RenderEngine::setCurrentSurface(const android::RE::impl::Surface& surface) { bool success = true; EGLSurface eglSurface = surface.getEGLSurface(); if (eglSurface != eglGetCurrentSurface(EGL_DRAW)) { @@ -349,7 +367,14 @@ void RenderEngine::deleteTextures(size_t count, uint32_t const* names) { glDeleteTextures(count, names); } -void RenderEngine::bindExternalTextureImage(uint32_t texName, const RE::Image& image) { +void RenderEngine::bindExternalTextureImage(uint32_t texName, const android::RE::Image& image) { + // Note: RE::Image is an abstract interface. This implementation only ever + // creates RE::impl::Image's, so it is safe to just cast to the actual type. + return bindExternalTextureImage(texName, static_cast(image)); +} + +void RenderEngine::bindExternalTextureImage(uint32_t texName, + const android::RE::impl::Image& image) { const GLenum target = GL_TEXTURE_EXTERNAL_OES; glBindTexture(target, texName); @@ -375,34 +400,33 @@ void RenderEngine::dump(String8& result) { // --------------------------------------------------------------------------- -RenderEngine::BindNativeBufferAsFramebuffer::BindNativeBufferAsFramebuffer( - RenderEngine& engine, ANativeWindowBuffer* buffer) - : mEngine(engine) { - mImage = eglCreateImageKHR(mEngine.mEGLDisplay, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, - buffer, nullptr); - if (mImage == EGL_NO_IMAGE_KHR) { - mStatus = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; +void RenderEngine::bindNativeBufferAsFrameBuffer(ANativeWindowBuffer* buffer, + RE::BindNativeBufferAsFramebuffer* bindHelper) { + bindHelper->mImage = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, + buffer, nullptr); + if (bindHelper->mImage == EGL_NO_IMAGE_KHR) { + bindHelper->mStatus = NO_MEMORY; return; } - mEngine.bindImageAsFramebuffer(mImage, &mTexName, &mFbName, &mStatus); + uint32_t glStatus; + bindImageAsFramebuffer(bindHelper->mImage, &bindHelper->mTexName, &bindHelper->mFbName, + &glStatus); - ALOGE_IF(mStatus != GL_FRAMEBUFFER_COMPLETE_OES, "glCheckFramebufferStatusOES error %d", - mStatus); + ALOGE_IF(glStatus != GL_FRAMEBUFFER_COMPLETE_OES, "glCheckFramebufferStatusOES error %d", + glStatus); + + bindHelper->mStatus = glStatus == GL_FRAMEBUFFER_COMPLETE_OES ? NO_ERROR : BAD_VALUE; } -RenderEngine::BindNativeBufferAsFramebuffer::~BindNativeBufferAsFramebuffer() { - if (mImage == EGL_NO_IMAGE_KHR) { +void RenderEngine::unbindNativeBufferAsFrameBuffer(RE::BindNativeBufferAsFramebuffer* bindHelper) { + if (bindHelper->mImage == EGL_NO_IMAGE_KHR) { return; } // back to main framebuffer - mEngine.unbindFramebuffer(mTexName, mFbName); - eglDestroyImageKHR(mEngine.mEGLDisplay, mImage); -} - -status_t RenderEngine::BindNativeBufferAsFramebuffer::getStatus() const { - return mStatus == GL_FRAMEBUFFER_COMPLETE_OES ? NO_ERROR : BAD_VALUE; + unbindFramebuffer(bindHelper->mTexName, bindHelper->mFbName); + eglDestroyImageKHR(mEGLDisplay, bindHelper->mImage); } // --------------------------------------------------------------------------- @@ -564,5 +588,7 @@ void RenderEngine::primeCache() const { } // --------------------------------------------------------------------------- -}; // namespace android -// --------------------------------------------------------------------------- + +} // namespace impl +} // namespace RE +} // namespace android diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.h b/services/surfaceflinger/RenderEngine/RenderEngine.h index 67c0d1c139..eacef384b7 100644 --- a/services/surfaceflinger/RenderEngine/RenderEngine.h +++ b/services/surfaceflinger/RenderEngine/RenderEngine.h @@ -44,91 +44,63 @@ class Mesh; class Texture; namespace RE { + class Image; class Surface; -} // namespace RE +class BindNativeBufferAsFramebuffer; -class RenderEngine { - enum GlesVersion { - GLES_VERSION_1_0 = 0x10000, - GLES_VERSION_1_1 = 0x10001, - GLES_VERSION_2_0 = 0x20000, - GLES_VERSION_3_0 = 0x30000, - }; - static GlesVersion parseGlesVersion(const char* str); - - EGLDisplay mEGLDisplay; - EGLConfig mEGLConfig; - EGLContext mEGLContext; - void setEGLHandles(EGLDisplay display, EGLConfig config, EGLContext ctxt); - - virtual void bindImageAsFramebuffer(EGLImageKHR image, uint32_t* texName, uint32_t* fbName, - uint32_t* status) = 0; - virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName) = 0; - - static bool overrideUseContextPriorityFromConfig(bool useContextPriority); - -protected: - RenderEngine(); +namespace impl { +class RenderEngine; +} +class RenderEngine { public: - virtual ~RenderEngine() = 0; - enum FeatureFlag { WIDE_COLOR_SUPPORT = 1 << 0 // Platform has a wide color display }; - static std::unique_ptr create(int hwcFormat, uint32_t featureFlags); - static EGLConfig chooseEglConfig(EGLDisplay display, int format, bool logConfig); + virtual ~RenderEngine() = 0; - void primeCache() const; + virtual std::unique_ptr createSurface() = 0; + virtual std::unique_ptr createImage() = 0; - // dump the extension strings. always call the base class. - virtual void dump(String8& result); + virtual void primeCache() const = 0; - bool supportsImageCrop() const; + // dump the extension strings. always call the base class. + virtual void dump(String8& result) = 0; - bool isCurrent() const; - bool setCurrentSurface(const RE::Surface& surface); - void resetCurrentSurface(); + virtual bool supportsImageCrop() const = 0; - // synchronization + virtual bool isCurrent() const = 0; + virtual bool setCurrentSurface(const RE::Surface& surface) = 0; + virtual void resetCurrentSurface() = 0; + // helpers // flush submits RenderEngine command stream for execution and returns a // native fence fd that is signaled when the execution has completed. It // returns -1 on errors. - base::unique_fd flush(); + virtual base::unique_fd flush() = 0; // finish waits until RenderEngine command stream has been executed. It // returns false on errors. - bool finish(); + virtual bool finish() = 0; // waitFence inserts a wait on an external fence fd to RenderEngine // command stream. It returns false on errors. - bool waitFence(base::unique_fd fenceFd); + virtual bool waitFence(base::unique_fd fenceFd) = 0; - // helpers - void clearWithColor(float red, float green, float blue, float alpha); - void fillRegionWithColor(const Region& region, uint32_t height, float red, float green, - float blue, float alpha); + virtual void clearWithColor(float red, float green, float blue, float alpha) = 0; + virtual void fillRegionWithColor(const Region& region, uint32_t height, float red, float green, + float blue, float alpha) = 0; // common to all GL versions - void setScissor(uint32_t left, uint32_t bottom, uint32_t right, uint32_t top); - void disableScissor(); - void genTextures(size_t count, uint32_t* names); - void deleteTextures(size_t count, uint32_t const* names); - void bindExternalTextureImage(uint32_t texName, const RE::Image& image); - void readPixels(size_t l, size_t b, size_t w, size_t h, uint32_t* pixels); - - class BindNativeBufferAsFramebuffer { - RenderEngine& mEngine; - EGLImageKHR mImage; - uint32_t mTexName, mFbName; - uint32_t mStatus; - - public: - BindNativeBufferAsFramebuffer(RenderEngine& engine, ANativeWindowBuffer* buffer); - ~BindNativeBufferAsFramebuffer(); - int getStatus() const; - }; + virtual void setScissor(uint32_t left, uint32_t bottom, uint32_t right, uint32_t top) = 0; + virtual void disableScissor() = 0; + virtual void genTextures(size_t count, uint32_t* names) = 0; + virtual void deleteTextures(size_t count, uint32_t const* names) = 0; + virtual void bindExternalTextureImage(uint32_t texName, const RE::Image& image) = 0; + virtual void readPixels(size_t l, size_t b, size_t w, size_t h, uint32_t* pixels) = 0; + virtual void bindNativeBufferAsFrameBuffer(ANativeWindowBuffer* buffer, + RE::BindNativeBufferAsFramebuffer* bindHelper) = 0; + virtual void unbindNativeBufferAsFrameBuffer(RE::BindNativeBufferAsFramebuffer* bindHelper) = 0; // set-up virtual void checkErrors() const; @@ -145,7 +117,7 @@ public: virtual void setupLayerBlackedOut() = 0; virtual void setupFillWithColor(float r, float g, float b, float a) = 0; - virtual mat4 setupColorTransform(const mat4& /* colorTransform */) { return mat4(); } + virtual mat4 setupColorTransform(const mat4& /* colorTransform */) = 0; virtual void disableTexturing() = 0; virtual void disableBlending() = 0; @@ -156,14 +128,123 @@ public: // queries virtual size_t getMaxTextureSize() const = 0; virtual size_t getMaxViewportDims() const = 0; +}; + +class BindNativeBufferAsFramebuffer { +public: + BindNativeBufferAsFramebuffer(RenderEngine& engine, ANativeWindowBuffer* buffer) + : mEngine(engine) { + mEngine.bindNativeBufferAsFrameBuffer(buffer, this); + } + ~BindNativeBufferAsFramebuffer() { mEngine.unbindNativeBufferAsFrameBuffer(this); } + status_t getStatus() const { return mStatus; } + +protected: + friend impl::RenderEngine; + + RenderEngine& mEngine; + EGLImageKHR mImage; + uint32_t mTexName, mFbName; + status_t mStatus; +}; + +namespace impl { + +class Image; +class Surface; + +class RenderEngine : public RE::RenderEngine { + enum GlesVersion { + GLES_VERSION_1_0 = 0x10000, + GLES_VERSION_1_1 = 0x10001, + GLES_VERSION_2_0 = 0x20000, + GLES_VERSION_3_0 = 0x30000, + }; + static GlesVersion parseGlesVersion(const char* str); + + EGLDisplay mEGLDisplay; + EGLConfig mEGLConfig; + EGLContext mEGLContext; + void setEGLHandles(EGLDisplay display, EGLConfig config, EGLContext ctxt); + + static bool overrideUseContextPriorityFromConfig(bool useContextPriority); + +protected: + RenderEngine(); + +public: + virtual ~RenderEngine() = 0; + + static std::unique_ptr create(int hwcFormat, uint32_t featureFlags); + + static EGLConfig chooseEglConfig(EGLDisplay display, int format, bool logConfig); + + // RenderEngine interface implementation + + std::unique_ptr createSurface() override; + std::unique_ptr createImage() override; + + void primeCache() const override; + + // dump the extension strings. always call the base class. + void dump(String8& result) override; + + bool supportsImageCrop() const override; + + bool isCurrent() const; + bool setCurrentSurface(const RE::Surface& surface) override; + void resetCurrentSurface() override; + + // synchronization + + // flush submits RenderEngine command stream for execution and returns a + // native fence fd that is signaled when the execution has completed. It + // returns -1 on errors. + base::unique_fd flush() override; + // finish waits until RenderEngine command stream has been executed. It + // returns false on errors. + bool finish() override; + // waitFence inserts a wait on an external fence fd to RenderEngine + // command stream. It returns false on errors. + bool waitFence(base::unique_fd fenceFd) override; + + // helpers + void clearWithColor(float red, float green, float blue, float alpha) override; + void fillRegionWithColor(const Region& region, uint32_t height, float red, float green, + float blue, float alpha) override; + + // common to all GL versions + void setScissor(uint32_t left, uint32_t bottom, uint32_t right, uint32_t top) override; + void disableScissor() override; + void genTextures(size_t count, uint32_t* names) override; + void deleteTextures(size_t count, uint32_t const* names) override; + void bindExternalTextureImage(uint32_t texName, const RE::Image& image) override; + void readPixels(size_t l, size_t b, size_t w, size_t h, uint32_t* pixels) override; + + void checkErrors() const override; + + mat4 setupColorTransform(const mat4& /* colorTransform */) override { return mat4(); } // internal to RenderEngine EGLDisplay getEGLDisplay() const; EGLConfig getEGLConfig() const; + + // Common implementation + bool setCurrentSurface(const RE::impl::Surface& surface); + void bindExternalTextureImage(uint32_t texName, const RE::impl::Image& image); + + void bindNativeBufferAsFrameBuffer(ANativeWindowBuffer* buffer, + RE::BindNativeBufferAsFramebuffer* bindHelper) override; + void unbindNativeBufferAsFrameBuffer(RE::BindNativeBufferAsFramebuffer* bindHelper) override; + + // Overriden by each specialization + virtual void bindImageAsFramebuffer(EGLImageKHR image, uint32_t* texName, uint32_t* fbName, + uint32_t* status) = 0; + virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName) = 0; }; -// --------------------------------------------------------------------------- -}; // namespace android -// --------------------------------------------------------------------------- +} // namespace impl +} // namespace RE +} // namespace android #endif /* SF_RENDERENGINE_H_ */ diff --git a/services/surfaceflinger/RenderEngine/Surface.cpp b/services/surfaceflinger/RenderEngine/Surface.cpp index a23d9fbb4e..3c29e4b2ea 100644 --- a/services/surfaceflinger/RenderEngine/Surface.cpp +++ b/services/surfaceflinger/RenderEngine/Surface.cpp @@ -23,6 +23,10 @@ namespace android { namespace RE { +Surface::~Surface() = default; + +namespace impl { + Surface::Surface(const RenderEngine& engine) : mEGLDisplay(engine.getEGLDisplay()), mEGLConfig(engine.getEGLConfig()) { // RE does not assume any config when EGL_KHR_no_config_context is supported @@ -102,5 +106,6 @@ int32_t Surface::queryHeight() const { return querySurface(EGL_HEIGHT); } +} // namespace impl } // namespace RE } // namespace android diff --git a/services/surfaceflinger/RenderEngine/Surface.h b/services/surfaceflinger/RenderEngine/Surface.h index 8b10be9303..d4d3d8c0f5 100644 --- a/services/surfaceflinger/RenderEngine/Surface.h +++ b/services/surfaceflinger/RenderEngine/Surface.h @@ -23,12 +23,32 @@ struct ANativeWindow; namespace android { - -class RenderEngine; - namespace RE { class Surface { +public: + virtual ~Surface() = 0; + + virtual void setCritical(bool enable) = 0; + virtual void setAsync(bool enable) = 0; + + virtual void setNativeWindow(ANativeWindow* window) = 0; + virtual void swapBuffers() const = 0; + + virtual int32_t queryRedSize() const = 0; + virtual int32_t queryGreenSize() const = 0; + virtual int32_t queryBlueSize() const = 0; + virtual int32_t queryAlphaSize() const = 0; + + virtual int32_t queryWidth() const = 0; + virtual int32_t queryHeight() const = 0; +}; + +namespace impl { + +class RenderEngine; + +class Surface final : public RE::Surface { public: Surface(const RenderEngine& engine); ~Surface(); @@ -36,26 +56,27 @@ public: Surface(const Surface&) = delete; Surface& operator=(const Surface&) = delete; - void setCritical(bool enable) { mCritical = enable; } - void setAsync(bool enable) { mAsync = enable; } + // RE::Surface implementation + void setCritical(bool enable) override { mCritical = enable; } + void setAsync(bool enable) override { mAsync = enable; } - void setNativeWindow(ANativeWindow* window); - void swapBuffers() const; + void setNativeWindow(ANativeWindow* window) override; + void swapBuffers() const override; - int32_t queryRedSize() const; - int32_t queryGreenSize() const; - int32_t queryBlueSize() const; - int32_t queryAlphaSize() const; + int32_t queryRedSize() const override; + int32_t queryGreenSize() const override; + int32_t queryBlueSize() const override; + int32_t queryAlphaSize() const override; - int32_t queryWidth() const; - int32_t queryHeight() const; + int32_t queryWidth() const override; + int32_t queryHeight() const override; private: EGLint queryConfig(EGLint attrib) const; EGLint querySurface(EGLint attrib) const; // methods internal to RenderEngine - friend class android::RenderEngine; + friend class RenderEngine; bool getAsync() const { return mAsync; } EGLSurface getEGLSurface() const { return mEGLSurface; } @@ -69,5 +90,6 @@ private: EGLSurface mEGLSurface = EGL_NO_SURFACE; }; +} // namespace impl } // namespace RE } // namespace android diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 1380b01a1c..7ad13e3ef2 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -410,12 +410,11 @@ void SurfaceFlinger::bootFinished() void SurfaceFlinger::deleteTextureAsync(uint32_t texture) { class MessageDestroyGLTexture : public MessageBase { - RenderEngine& engine; + RE::RenderEngine& engine; uint32_t texture; public: - MessageDestroyGLTexture(RenderEngine& engine, uint32_t texture) - : engine(engine), texture(texture) { - } + MessageDestroyGLTexture(RE::RenderEngine& engine, uint32_t texture) + : engine(engine), texture(texture) {} virtual bool handler() { engine.deleteTextures(1, &texture); return true; @@ -587,8 +586,11 @@ void SurfaceFlinger::init() { mEventQueue.setEventThread(mSFEventThread.get()); // Get a RenderEngine for the given display / config (can't fail) - getBE().mRenderEngine = RenderEngine::create(HAL_PIXEL_FORMAT_RGBA_8888, - hasWideColorDisplay ? RenderEngine::WIDE_COLOR_SUPPORT : 0); + getBE().mRenderEngine = + RE::impl::RenderEngine::create(HAL_PIXEL_FORMAT_RGBA_8888, + hasWideColorDisplay + ? RE::RenderEngine::WIDE_COLOR_SUPPORT + : 0); LOG_ALWAYS_FATAL_IF(getBE().mRenderEngine == nullptr, "couldn't create RenderEngine"); LOG_ALWAYS_FATAL_IF(mVrFlingerRequestsDisplay, @@ -1473,7 +1475,7 @@ void SurfaceFlinger::doDebugFlashRegions() // and draw the dirty region const int32_t height = hw->getHeight(); - RenderEngine& engine(getRenderEngine()); + auto& engine(getRenderEngine()); engine.fillRegionWithColor(dirtyRegion, height, 1, 0, 1, 1); hw->swapBuffers(getHwComposer()); @@ -2856,7 +2858,7 @@ bool SurfaceFlinger::doComposeSurfaces(const sp& displayDev void SurfaceFlinger::drawWormhole(const sp& displayDevice, const Region& region) const { const int32_t height = displayDevice->getHeight(); - RenderEngine& engine(getRenderEngine()); + auto& engine(getRenderEngine()); engine.fillRegionWithColor(region, height, 0, 0, 0, 0); } @@ -4518,7 +4520,7 @@ void SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea, bool useIdentityTransform) { ATRACE_CALL(); - RenderEngine& engine(getRenderEngine()); + auto& engine(getRenderEngine()); // get screen geometry const auto raWidth = renderArea.getWidth(); @@ -4597,7 +4599,7 @@ status_t SurfaceFlinger::captureScreenImplLocked(const RenderArea& renderArea, // this binds the given EGLImage as a framebuffer for the // duration of this scope. - RenderEngine::BindNativeBufferAsFramebuffer bufferBond(getRenderEngine(), buffer); + RE::BindNativeBufferAsFramebuffer bufferBond(getRenderEngine(), buffer); if (bufferBond.getStatus() != NO_ERROR) { ALOGE("got ANWB binding error while taking screenshot"); return INVALID_OPERATION; diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 19dd059e97..a17eb70882 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -83,16 +83,19 @@ namespace android { // --------------------------------------------------------------------------- class Client; +class ColorLayer; class DisplayEventConnection; +class EventControlThread; class EventThread; +class InjectVSyncSource; class Layer; -class ColorLayer; class Surface; -class RenderEngine; -class EventControlThread; -class VSyncSource; -class InjectVSyncSource; class SurfaceFlingerBE; +class VSyncSource; + +namespace RE { +class RenderEngine; +} typedef std::function TraverseLayersFunction; @@ -139,7 +142,7 @@ public: const std::string mHwcServiceName; // "default" for real use, something else for testing. // constant members (no synchronization needed for access) - std::unique_ptr mRenderEngine; + std::unique_ptr mRenderEngine; EGLContext mEGLContext; EGLDisplay mEGLDisplay; @@ -301,9 +304,7 @@ public: // TODO: this should be made accessible only to HWComposer const Vector< sp >& getLayerSortedByZForHwcDisplay(int id); - RenderEngine& getRenderEngine() const { - return *getBE().mRenderEngine; - } + RE::RenderEngine& getRenderEngine() const { return *getBE().mRenderEngine; } bool authenticateSurfaceTextureLocked( const sp& bufferProducer) const; -- cgit v1.2.3-59-g8ed1b From f9c98e552b2ca404200048d8a78244e4fa080223 Mon Sep 17 00:00:00 2001 From: Courtney Goeltzenleuchter Date: Mon, 12 Feb 2018 07:23:17 -0700 Subject: SF: Update to composer@2.2 implementation Bug: 63710530 Test: adb -d shell am start -n \ com.drawelements.deqp/android.app.NativeActivity \ -e cmdLine '"deqp --deqp-case=dEQP-EGL.functional.hdr_metadata.* \ --deqp-log-filename=/sdcard/dEQP-Log.qpa"' Change-Id: I5412eae0a001406e058cd6687b02f3a37c82a7f1 --- libs/vr/libvrflinger/Android.bp | 2 + services/surfaceflinger/Android.bp | 3 + services/surfaceflinger/BufferLayer.cpp | 7 ++ .../surfaceflinger/DisplayHardware/ComposerHal.cpp | 113 ++++++++++++++++++--- .../surfaceflinger/DisplayHardware/ComposerHal.h | 30 ++++-- services/surfaceflinger/DisplayHardware/HWC2.cpp | 14 ++- services/surfaceflinger/DisplayHardware/HWC2.h | 5 +- .../surfaceflinger/tests/unittests/MockComposer.h | 5 +- 8 files changed, 150 insertions(+), 29 deletions(-) (limited to 'services/surfaceflinger/BufferLayer.cpp') diff --git a/libs/vr/libvrflinger/Android.bp b/libs/vr/libvrflinger/Android.bp index 23a9853ce2..3e4a42cac9 100644 --- a/libs/vr/libvrflinger/Android.bp +++ b/libs/vr/libvrflinger/Android.bp @@ -39,6 +39,7 @@ sharedLibraries = [ "android.frameworks.vr.composer@1.0", "android.hardware.graphics.allocator@2.0", "android.hardware.graphics.composer@2.1", + "android.hardware.graphics.composer@2.2", "libbinder", "libbase", "libbufferhubqueue", @@ -62,6 +63,7 @@ sharedLibraries = [ headerLibraries = [ "android.hardware.graphics.composer@2.1-command-buffer", + "android.hardware.graphics.composer@2.2-command-buffer", "libdvr_headers", "libsurfaceflinger_headers", ] diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp index 3531c4ebd9..0c0fedc8b2 100644 --- a/services/surfaceflinger/Android.bp +++ b/services/surfaceflinger/Android.bp @@ -24,6 +24,7 @@ cc_defaults { "android.hardware.configstore@1.0", "android.hardware.graphics.allocator@2.0", "android.hardware.graphics.composer@2.1", + "android.hardware.graphics.composer@2.2", "android.hardware.power@1.0", "libbase", "libbinder", @@ -57,6 +58,7 @@ cc_defaults { ], header_libs: [ "android.hardware.graphics.composer@2.1-command-buffer", + "android.hardware.graphics.composer@2.2-command-buffer", ], export_static_lib_headers: [ "libserviceutils", @@ -64,6 +66,7 @@ cc_defaults { export_shared_lib_headers: [ "android.hardware.graphics.allocator@2.0", "android.hardware.graphics.composer@2.1", + "android.hardware.graphics.composer@2.2", "libhidlbase", "libhidltransport", "libhwbinder", diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index 3dbc136205..b804af8183 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -629,6 +629,13 @@ void BufferLayer::setPerFrameData(const sp& displayDevice) to_string(error).c_str(), static_cast(error)); } + const HdrMetadata& metadata = mConsumer->getCurrentHdrMetadata(); + error = hwcLayer->setHdrMetadata(metadata); + if (error != HWC2::Error::None) { + ALOGE("[%s] Failed to set hdrMetadata: %s (%d)", mName.string(), + to_string(error).c_str(), static_cast(error)); + } + uint32_t hwcSlot = 0; sp hwcBuffer; hwcInfo.bufferCache.getHwcBuffer(getBE().compositionInfo.mBufferSlot, diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp index 03b714f958..bb720f75d7 100644 --- a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp +++ b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp @@ -19,15 +19,23 @@ #include #include -#include #include "ComposerHal.h" +#include +#include +#include +#include + namespace android { using hardware::Return; using hardware::hidl_vec; using hardware::hidl_handle; +using namespace hardware::graphics::composer; +using PerFrameMetadata = hardware::graphics::composer::V2_2::IComposerClient::PerFrameMetadata; +using PerFrameMetadataKey = + hardware::graphics::composer::V2_2::IComposerClient::PerFrameMetadataKey; namespace Hwc2 { @@ -117,10 +125,9 @@ Composer::CommandWriter::~CommandWriter() void Composer::CommandWriter::setLayerInfo(uint32_t type, uint32_t appId) { constexpr uint16_t kSetLayerInfoLength = 2; - beginCommand( - static_cast( - IVrComposerClient::VrCommand::SET_LAYER_INFO), - kSetLayerInfoLength); + beginCommand(static_cast( + IVrComposerClient::VrCommand::SET_LAYER_INFO), + kSetLayerInfoLength); write(type); write(appId); endCommand(); @@ -130,10 +137,9 @@ void Composer::CommandWriter::setClientTargetMetadata( const IVrComposerClient::BufferMetadata& metadata) { constexpr uint16_t kSetClientTargetMetadataLength = 7; - beginCommand( - static_cast( - IVrComposerClient::VrCommand::SET_CLIENT_TARGET_METADATA), - kSetClientTargetMetadataLength); + beginCommand(static_cast( + IVrComposerClient::VrCommand::SET_CLIENT_TARGET_METADATA), + kSetClientTargetMetadataLength); writeBufferMetadata(metadata); endCommand(); } @@ -142,10 +148,9 @@ void Composer::CommandWriter::setLayerBufferMetadata( const IVrComposerClient::BufferMetadata& metadata) { constexpr uint16_t kSetLayerBufferMetadataLength = 7; - beginCommand( - static_cast( - IVrComposerClient::VrCommand::SET_LAYER_BUFFER_METADATA), - kSetLayerBufferMetadataLength); + beginCommand(static_cast( + IVrComposerClient::VrCommand::SET_LAYER_BUFFER_METADATA), + kSetLayerBufferMetadataLength); writeBufferMetadata(metadata); endCommand(); } @@ -182,6 +187,13 @@ Composer::Composer(const std::string& serviceName) LOG_ALWAYS_FATAL("failed to create composer client"); } + // 2.2 support is optional + sp composer_2_2 = V2_2::IComposer::castFrom(mComposer); + if (composer_2_2 != nullptr) { + mClient_2_2 = IComposerClient::castFrom(mClient); + LOG_ALWAYS_FATAL_IF(mClient_2_2 == nullptr, "IComposer 2.2 did not return IComposerClient 2.2"); + } + if (mIsUsingVrComposer) { sp vrClient = IVrComposerClient::castFrom(mClient); if (vrClient == nullptr) { @@ -451,6 +463,25 @@ Error Composer::getHdrCapabilities(Display display, return error; } +Error Composer::getPerFrameMetadataKeys( + Display display, std::vector* outKeys) { + if (!mClient_2_2) { + return Error::UNSUPPORTED; + } + + Error error = kDefaultError; + mClient_2_2->getPerFrameMetadataKeys(display, [&](const auto& tmpError, const auto& tmpKeys) { + error = tmpError; + if (error != Error::NONE) { + return; + } + + *outKeys = tmpKeys; + }); + + return error; +} + Error Composer::getReleaseFences(Display display, std::vector* outLayers, std::vector* outReleaseFences) { @@ -530,7 +561,15 @@ Error Composer::setOutputBuffer(Display display, const native_handle_t* buffer, Error Composer::setPowerMode(Display display, IComposerClient::PowerMode mode) { - auto ret = mClient->setPowerMode(display, mode); + hardware::Return ret(Error::UNSUPPORTED); + if (mClient_2_2) { + ret = mClient_2_2->setPowerMode_2_2(display, mode); + } else if (mode != IComposerClient::PowerMode::ON_SUSPEND) { + ret = mClient->setPowerMode(display, + static_cast(mode)); + } + return unwrapRet(ret); } @@ -666,6 +705,44 @@ Error Composer::setLayerDataspace(Display display, Layer layer, return Error::NONE; } +Error Composer::setLayerHdrMetadata(Display display, Layer layer, const HdrMetadata& metadata) { + + mWriter.selectDisplay(display); + mWriter.selectLayer(layer); + + std::vector composerMetadata; + if (metadata.validTypes & HdrMetadata::SMPTE2086) { + composerMetadata + .insert(composerMetadata.end(), + {{PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X, + metadata.smpte2086.displayPrimaryRed.x}, + {PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y, + metadata.smpte2086.displayPrimaryRed.y}, + {PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X, + metadata.smpte2086.displayPrimaryGreen.x}, + {PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y, + metadata.smpte2086.displayPrimaryGreen.y}, + {PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X, + metadata.smpte2086.displayPrimaryBlue.x}, + {PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y, + metadata.smpte2086.displayPrimaryBlue.y}, + {PerFrameMetadataKey::WHITE_POINT_X, metadata.smpte2086.whitePoint.x}, + {PerFrameMetadataKey::WHITE_POINT_Y, metadata.smpte2086.whitePoint.y}, + {PerFrameMetadataKey::MAX_LUMINANCE, metadata.smpte2086.maxLuminance}, + {PerFrameMetadataKey::MIN_LUMINANCE, metadata.smpte2086.minLuminance}}); + } + if (metadata.validTypes & HdrMetadata::CTA861_3) { + composerMetadata.insert(composerMetadata.end(), + {{PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL, + metadata.cta8613.maxContentLightLevel}, + {PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL, + metadata.cta8613.maxFrameAverageLightLevel}}); + } + + mWriter.setPerFrameMetadata(composerMetadata); + return Error::NONE; +} + Error Composer::setLayerDisplayFrame(Display display, Layer layer, const IComposerClient::Rect& frame) { @@ -810,7 +887,8 @@ Error Composer::execute() mReader.takeErrors(); for (const auto& cmdErr : commandErrors) { - auto command = mWriter.getCommand(cmdErr.location); + auto command = + static_cast(mWriter.getCommand(cmdErr.location)); if (command == IComposerClient::Command::VALIDATE_DISPLAY || command == IComposerClient::Command::PRESENT_DISPLAY || @@ -841,7 +919,10 @@ Error CommandReader::parse() uint16_t length = 0; while (!isEmpty()) { - if (!beginCommand(&command, &length)) { + auto command_2_1 = + reinterpret_cast( + &command); + if (!beginCommand(command_2_1, &length)) { break; } diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h index 77675fbce2..c0373aa6c1 100644 --- a/services/surfaceflinger/DisplayHardware/ComposerHal.h +++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h @@ -24,8 +24,10 @@ #include #include -#include -#include +#include +#include +#include +#include #include #include @@ -42,16 +44,16 @@ using android::hardware::graphics::common::V1_0::Hdr; using android::hardware::graphics::common::V1_0::PixelFormat; using android::hardware::graphics::common::V1_0::Transform; +using android::hardware::graphics::composer::V2_1::Config; +using android::hardware::graphics::composer::V2_1::Display; +using android::hardware::graphics::composer::V2_1::Error; using android::hardware::graphics::composer::V2_1::IComposer; using android::hardware::graphics::composer::V2_1::IComposerCallback; -using android::hardware::graphics::composer::V2_1::IComposerClient; -using android::hardware::graphics::composer::V2_1::Error; -using android::hardware::graphics::composer::V2_1::Display; using android::hardware::graphics::composer::V2_1::Layer; -using android::hardware::graphics::composer::V2_1::Config; +using android::hardware::graphics::composer::V2_2::IComposerClient; -using android::hardware::graphics::composer::V2_1::CommandWriterBase; -using android::hardware::graphics::composer::V2_1::CommandReaderBase; +using android::hardware::graphics::composer::V2_2::CommandReaderBase; +using android::hardware::graphics::composer::V2_2::CommandWriterBase; using android::hardware::kSynchronizedReadWrite; using android::hardware::MessageQueue; @@ -111,6 +113,9 @@ public: float* outMaxLuminance, float* outMaxAverageLuminance, float* outMinLuminance) = 0; + virtual Error getPerFrameMetadataKeys( + Display display, std::vector* outKeys) = 0; + virtual Error getReleaseFences(Display display, std::vector* outLayers, std::vector* outReleaseFences) = 0; @@ -155,6 +160,8 @@ public: virtual Error setLayerCompositionType(Display display, Layer layer, IComposerClient::Composition type) = 0; virtual Error setLayerDataspace(Display display, Layer layer, Dataspace dataspace) = 0; + virtual Error setLayerHdrMetadata(Display display, Layer layer, + const HdrMetadata& metadata) = 0; virtual Error setLayerDisplayFrame(Display display, Layer layer, const IComposerClient::Rect& frame) = 0; virtual Error setLayerPlaneAlpha(Display display, Layer layer, float alpha) = 0; @@ -298,6 +305,9 @@ public: Error getHdrCapabilities(Display display, std::vector* outTypes, float* outMaxLuminance, float* outMaxAverageLuminance, float* outMinLuminance) override; + Error getPerFrameMetadataKeys( + Display display, std::vector* outKeys) override; + Error getReleaseFences(Display display, std::vector* outLayers, std::vector* outReleaseFences) override; @@ -339,6 +349,7 @@ public: Error setLayerCompositionType(Display display, Layer layer, IComposerClient::Composition type) override; Error setLayerDataspace(Display display, Layer layer, Dataspace dataspace) override; + Error setLayerHdrMetadata(Display display, Layer layer, const HdrMetadata& metadata) override; Error setLayerDisplayFrame(Display display, Layer layer, const IComposerClient::Rect& frame) override; Error setLayerPlaneAlpha(Display display, Layer layer, float alpha) override; @@ -375,7 +386,8 @@ private: Error execute(); sp mComposer; - sp mClient; + sp mClient; + sp mClient_2_2; // 64KiB minus a small space for metadata such as read/write pointers static constexpr size_t kWriterInitialSize = diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp index 814b55e19a..f14c2fe10b 100644 --- a/services/surfaceflinger/DisplayHardware/HWC2.cpp +++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp @@ -37,6 +37,7 @@ using android::Fence; using android::FloatRect; using android::GraphicBuffer; using android::HdrCapabilities; +using android::HdrMetadata; using android::Rect; using android::Region; using android::sp; @@ -687,8 +688,7 @@ Layer* Display::getLayerById(hwc2_layer_t id) const // Layer methods -Layer::Layer(android::Hwc2::Composer& composer, - const std::unordered_set& capabilities, +Layer::Layer(android::Hwc2::Composer& composer, const std::unordered_set& capabilities, hwc2_display_t displayId, hwc2_layer_t layerId) : mComposer(composer), mCapabilities(capabilities), @@ -788,6 +788,16 @@ Error Layer::setDataspace(android_dataspace_t dataspace) return static_cast(intError); } +Error Layer::setHdrMetadata(const android::HdrMetadata& metadata) { + if (metadata == mHdrMetadata) { + return Error::None; + } + + mHdrMetadata = metadata; + auto intError = mComposer.setLayerHdrMetadata(mDisplayId, mId, metadata); + return static_cast(intError); +} + Error Layer::setDisplayFrame(const Rect& frame) { Hwc2::IComposerClient::Rect hwcRect{frame.left, frame.top, diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h index aade4e0b0d..e74f00dccc 100644 --- a/services/surfaceflinger/DisplayHardware/HWC2.h +++ b/services/surfaceflinger/DisplayHardware/HWC2.h @@ -23,8 +23,9 @@ #undef HWC2_INCLUDE_STRINGIFICATION #undef HWC2_USE_CPP11 -#include +#include #include +#include #include #include @@ -306,6 +307,7 @@ public: [[clang::warn_unused_result]] Error setCompositionType(Composition type); [[clang::warn_unused_result]] Error setDataspace( android_dataspace_t dataspace); + [[clang::warn_unused_result]] Error setHdrMetadata(const android::HdrMetadata& metadata); [[clang::warn_unused_result]] Error setDisplayFrame( const android::Rect& frame); [[clang::warn_unused_result]] Error setPlaneAlpha(float alpha); @@ -329,6 +331,7 @@ private: hwc2_display_t mDisplayId; hwc2_layer_t mId; android_dataspace mDataSpace = HAL_DATASPACE_UNKNOWN; + android::HdrMetadata mHdrMetadata; std::function mLayerDestroyedListener; }; diff --git a/services/surfaceflinger/tests/unittests/MockComposer.h b/services/surfaceflinger/tests/unittests/MockComposer.h index 248afcf1ac..acd9b3099a 100644 --- a/services/surfaceflinger/tests/unittests/MockComposer.h +++ b/services/surfaceflinger/tests/unittests/MockComposer.h @@ -39,8 +39,8 @@ using android::hardware::graphics::composer::V2_1::Display; using android::hardware::graphics::composer::V2_1::Error; using android::hardware::graphics::composer::V2_1::IComposer; using android::hardware::graphics::composer::V2_1::IComposerCallback; -using android::hardware::graphics::composer::V2_1::IComposerClient; using android::hardware::graphics::composer::V2_1::Layer; +using android::hardware::graphics::composer::V2_2::IComposerClient; class Composer : public Hwc2::Composer { public: @@ -73,6 +73,8 @@ public: MOCK_METHOD2(getDisplayType, Error(Display, IComposerClient::DisplayType*)); MOCK_METHOD2(getDozeSupport, Error(Display, bool*)); MOCK_METHOD5(getHdrCapabilities, Error(Display, std::vector*, float*, float*, float*)); + MOCK_METHOD2(getPerFrameMetadataKeys, + Error(Display, std::vector*)); MOCK_METHOD3(getReleaseFences, Error(Display, std::vector*, std::vector*)); MOCK_METHOD2(presentDisplay, Error(Display, int*)); MOCK_METHOD2(setActiveConfig, Error(Display, Config)); @@ -95,6 +97,7 @@ public: MOCK_METHOD3(setLayerColor, Error(Display, Layer, const IComposerClient::Color&)); MOCK_METHOD3(setLayerCompositionType, Error(Display, Layer, IComposerClient::Composition)); MOCK_METHOD3(setLayerDataspace, Error(Display, Layer, Dataspace)); + MOCK_METHOD3(setLayerHdrMetadata, Error(Display, Layer, const HdrMetadata&)); MOCK_METHOD3(setLayerDisplayFrame, Error(Display, Layer, const IComposerClient::Rect&)); MOCK_METHOD3(setLayerPlaneAlpha, Error(Display, Layer, float)); MOCK_METHOD3(setLayerSidebandStream, Error(Display, Layer, const native_handle_t*)); -- cgit v1.2.3-59-g8ed1b From 301bb3097c267e6dbab25f6099403269b75a4e1c Mon Sep 17 00:00:00 2001 From: Courtney Goeltzenleuchter Date: Mon, 12 Mar 2018 11:12:42 -0600 Subject: Do not send HdrMetadata on older interface Need to make sure composer@2.2 is supported before sending HDR data across composer interface. Test: boot Bug: 74523164 Change-Id: I551c8568098990193309939483f10a30cc47350c --- services/surfaceflinger/BufferLayer.cpp | 2 +- services/surfaceflinger/DisplayHardware/ComposerHal.cpp | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'services/surfaceflinger/BufferLayer.cpp') diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index b804af8183..d22c021139 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -631,7 +631,7 @@ void BufferLayer::setPerFrameData(const sp& displayDevice) const HdrMetadata& metadata = mConsumer->getCurrentHdrMetadata(); error = hwcLayer->setHdrMetadata(metadata); - if (error != HWC2::Error::None) { + if (error != HWC2::Error::None && error != HWC2::Error::Unsupported) { ALOGE("[%s] Failed to set hdrMetadata: %s (%d)", mName.string(), to_string(error).c_str(), static_cast(error)); } diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp index bb720f75d7..0425a8a216 100644 --- a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp +++ b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp @@ -706,6 +706,9 @@ Error Composer::setLayerDataspace(Display display, Layer layer, } Error Composer::setLayerHdrMetadata(Display display, Layer layer, const HdrMetadata& metadata) { + if (!mClient_2_2) { + return Error::UNSUPPORTED; + } mWriter.selectDisplay(display); mWriter.selectLayer(layer); -- cgit v1.2.3-59-g8ed1b From 4d2348551e73b4990aedc83db17a336b533316e6 Mon Sep 17 00:00:00 2001 From: Lloyd Pique Date: Mon, 22 Jan 2018 17:21:36 -0800 Subject: SF: Separate SurfaceInterceptor into interface and impl SurfaceInterceptor is now an abstract interface. impl::SurfaceInterceptor is the normal implementation. This allows unit tests to replace it with a GMock. Test: Builds Bug: 74827900 Change-Id: I4d5bb2649b0c7a8ec1e6c0abf01ab53174d06a19 (cherry picked from commit 4dccc413ddf822ca6f1856fd2d8ab80185203eed) --- services/surfaceflinger/BufferLayer.cpp | 6 +-- services/surfaceflinger/EventThread.cpp | 2 +- services/surfaceflinger/Layer.h | 6 ++- services/surfaceflinger/SurfaceFlinger.cpp | 25 +++++---- services/surfaceflinger/SurfaceFlinger.h | 3 +- services/surfaceflinger/SurfaceInterceptor.cpp | 6 ++- services/surfaceflinger/SurfaceInterceptor.h | 72 ++++++++++++++++++++------ 7 files changed, 85 insertions(+), 35 deletions(-) (limited to 'services/surfaceflinger/BufferLayer.cpp') diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index d22c021139..9200207f4a 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -690,9 +690,9 @@ void BufferLayer::onFrameAvailable(const BufferItem& item) { // Add this buffer from our internal queue tracker { // Autolock scope Mutex::Autolock lock(mQueueItemLock); - mFlinger->mInterceptor.saveBufferUpdate(this, item.mGraphicBuffer->getWidth(), - item.mGraphicBuffer->getHeight(), - item.mFrameNumber); + mFlinger->mInterceptor->saveBufferUpdate(this, item.mGraphicBuffer->getWidth(), + item.mGraphicBuffer->getHeight(), + item.mFrameNumber); // Reset the frame number tracker when we receive the first buffer after // a frame number reset if (item.mFrameNumber == 1) { diff --git a/services/surfaceflinger/EventThread.cpp b/services/surfaceflinger/EventThread.cpp index 1f4f5a53f4..bb9c0703ed 100644 --- a/services/surfaceflinger/EventThread.cpp +++ b/services/surfaceflinger/EventThread.cpp @@ -217,7 +217,7 @@ Vector > EventThread::waitForEventLocked( if (timestamp) { // we have a vsync event to dispatch if (mInterceptVSyncs) { - mFlinger.mInterceptor.saveVSyncEvent(timestamp); + mFlinger.mInterceptor->saveVSyncEvent(timestamp); } *event = mVSyncEvent[i]; mVSyncEvent[i].header.timestamp = 0; diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 996d686371..3d572c67fb 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -66,6 +66,10 @@ class SurfaceFlinger; class LayerDebugInfo; class LayerBE; +namespace impl { +class SurfaceInterceptor; +} + // --------------------------------------------------------------------------- struct CompositionInfo { @@ -593,7 +597,7 @@ protected: virtual void onFirstRef(); - friend class SurfaceInterceptor; + friend class impl::SurfaceInterceptor; void commitTransaction(const State& stateToCommit); diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index e5a15d58af..932b92e653 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -186,7 +186,6 @@ SurfaceFlinger::SurfaceFlinger(SurfaceFlinger::SkipInitializationTag) mLastTransactionTime(0), mBootFinished(false), mForceFullDamage(false), - mInterceptor(this), mPrimaryDispSync("PrimaryDispSync"), mPrimaryHWVsyncEnabled(false), mHWVsyncAvailable(false), @@ -350,7 +349,7 @@ sp SurfaceFlinger::createDisplay(const String8& displayName, DisplayDeviceState info(DisplayDevice::DISPLAY_VIRTUAL, secure); info.displayName = displayName; mCurrentState.displays.add(token, info); - mInterceptor.saveDisplayCreation(info); + mInterceptor->saveDisplayCreation(info); return token; } @@ -368,7 +367,7 @@ void SurfaceFlinger::destroyDisplay(const sp& display) { ALOGE("destroyDisplay called for non-virtual display"); return; } - mInterceptor.saveDisplayDeletion(info.displayId); + mInterceptor->saveDisplayDeletion(info.displayId); mCurrentState.displays.removeItemsAt(idx); setTransactionFlags(eDisplayTransactionNeeded); } @@ -2131,7 +2130,7 @@ void SurfaceFlinger::processDisplayHotplugEventsLocked() { info.displayName = displayType == DisplayDevice::DISPLAY_PRIMARY ? "Built-in Screen" : "External Screen"; mCurrentState.displays.add(mBuiltinDisplays[displayType], info); - mInterceptor.saveDisplayCreation(info); + mInterceptor->saveDisplayCreation(info); } } else { ALOGV("Removing built in display %d", displayType); @@ -2139,7 +2138,7 @@ void SurfaceFlinger::processDisplayHotplugEventsLocked() { ssize_t idx = mCurrentState.displays.indexOfKey(mBuiltinDisplays[displayType]); if (idx >= 0) { const DisplayDeviceState& info(mCurrentState.displays.valueAt(idx)); - mInterceptor.saveDisplayDeletion(info.displayId); + mInterceptor->saveDisplayDeletion(info.displayId); mCurrentState.displays.removeItemsAt(idx); } mBuiltinDisplays[displayType].clear(); @@ -3066,8 +3065,8 @@ void SurfaceFlinger::setTransactionState( } if (transactionFlags) { - if (mInterceptor.isEnabled()) { - mInterceptor.saveTransaction(states, mCurrentState.displays, displays, flags); + if (mInterceptor->isEnabled()) { + mInterceptor->saveTransaction(states, mCurrentState.displays, displays, flags); } // this triggers the transaction @@ -3370,7 +3369,7 @@ status_t SurfaceFlinger::createLayer( if (result != NO_ERROR) { return result; } - mInterceptor.saveSurfaceCreation(layer); + mInterceptor->saveSurfaceCreation(layer); setTransactionFlags(eTransactionNeeded); return result; @@ -3442,7 +3441,7 @@ status_t SurfaceFlinger::onLayerRemoved(const sp& client, const sp l(client->getLayerUser(handle)); if (l != nullptr) { - mInterceptor.saveSurfaceDeletion(l); + mInterceptor->saveSurfaceDeletion(l); err = removeLayer(l); ALOGE_IF(err<0 && err != NAME_NOT_FOUND, "error removing layer=%p (%s)", l.get(), strerror(-err)); @@ -3524,14 +3523,14 @@ void SurfaceFlinger::setPowerModeInternal(const sp& hw, return; } - if (mInterceptor.isEnabled()) { + if (mInterceptor->isEnabled()) { ConditionalLock lock(mStateLock, !stateLockHeld); ssize_t idx = mCurrentState.displays.indexOfKey(hw->getDisplayToken()); if (idx < 0) { ALOGW("Surface Interceptor SavePowerMode: invalid display token"); return; } - mInterceptor.savePowerModeUpdate(mCurrentState.displays.valueAt(idx).displayId, mode); + mInterceptor->savePowerModeUpdate(mCurrentState.displays.valueAt(idx).displayId, mode); } if (currentMode == HWC_POWER_MODE_OFF) { @@ -4335,11 +4334,11 @@ status_t SurfaceFlinger::onTransact( n = data.readInt32(); if (n) { ALOGV("Interceptor enabled"); - mInterceptor.enable(mDrawingState.layersSortedByZ, mDrawingState.displays); + mInterceptor->enable(mDrawingState.layersSortedByZ, mDrawingState.displays); } else{ ALOGV("Interceptor disabled"); - mInterceptor.disable(); + mInterceptor->disable(); } return NO_ERROR; } diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 989e20d6fe..7d15622d4f 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -777,7 +777,8 @@ private: bool mBootFinished; bool mForceFullDamage; bool mPropagateBackpressure = true; - SurfaceInterceptor mInterceptor; + std::unique_ptr mInterceptor = + std::make_unique(this); SurfaceTracing mTracing; bool mUseHwcVirtualDisplays = false; diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp index eeb492978c..4596a21f12 100644 --- a/services/surfaceflinger/SurfaceInterceptor.cpp +++ b/services/surfaceflinger/SurfaceInterceptor.cpp @@ -31,6 +31,10 @@ namespace android { // ---------------------------------------------------------------------------- +SurfaceInterceptor::~SurfaceInterceptor() = default; + +namespace impl { + SurfaceInterceptor::SurfaceInterceptor(SurfaceFlinger* flinger) : mFlinger(flinger) { @@ -593,5 +597,5 @@ void SurfaceInterceptor::savePowerModeUpdate(int32_t displayId, int32_t mode) { addPowerModeUpdateLocked(createTraceIncrementLocked(), displayId, mode); } - +} // namespace impl } // namespace android diff --git a/services/surfaceflinger/SurfaceInterceptor.h b/services/surfaceflinger/SurfaceInterceptor.h index 30ebcc6a1c..96defcc265 100644 --- a/services/surfaceflinger/SurfaceInterceptor.h +++ b/services/surfaceflinger/SurfaceInterceptor.h @@ -21,48 +21,89 @@ #include +#include + +#include #include +#include #include +#include "DisplayDevice.h" + namespace android { class BufferItem; class Layer; class SurfaceFlinger; +struct ComposerState; +struct DisplayDeviceState; struct DisplayState; struct layer_state_t; constexpr auto DEFAULT_FILENAME = "/data/SurfaceTrace.dat"; +class SurfaceInterceptor { +public: + virtual ~SurfaceInterceptor(); + + // Both vectors are used to capture the current state of SF as the initial snapshot in the trace + virtual void enable(const SortedVector>& layers, + const DefaultKeyedVector, DisplayDeviceState>& displays) = 0; + virtual void disable() = 0; + virtual bool isEnabled() = 0; + + // Intercept display and surface transactions + virtual void saveTransaction( + const Vector& stateUpdates, + const DefaultKeyedVector, DisplayDeviceState>& displays, + const Vector& changedDisplays, uint32_t flags) = 0; + + // Intercept surface data + virtual void saveSurfaceCreation(const sp& layer) = 0; + virtual void saveSurfaceDeletion(const sp& layer) = 0; + virtual void saveBufferUpdate(const sp& layer, uint32_t width, uint32_t height, + uint64_t frameNumber) = 0; + + // Intercept display data + virtual void saveDisplayCreation(const DisplayDeviceState& info) = 0; + virtual void saveDisplayDeletion(int32_t displayId) = 0; + virtual void savePowerModeUpdate(int32_t displayId, int32_t mode) = 0; + virtual void saveVSyncEvent(nsecs_t timestamp) = 0; +}; + +namespace impl { + /* * SurfaceInterceptor intercepts and stores incoming streams of window * properties on SurfaceFlinger. */ -class SurfaceInterceptor { +class SurfaceInterceptor final : public android::SurfaceInterceptor { public: - SurfaceInterceptor(SurfaceFlinger* const flinger); + explicit SurfaceInterceptor(SurfaceFlinger* const flinger); + ~SurfaceInterceptor() override = default; + // Both vectors are used to capture the current state of SF as the initial snapshot in the trace void enable(const SortedVector>& layers, - const DefaultKeyedVector< wp, DisplayDeviceState>& displays); - void disable(); - bool isEnabled(); + const DefaultKeyedVector, DisplayDeviceState>& displays) override; + void disable() override; + bool isEnabled() override; // Intercept display and surface transactions void saveTransaction(const Vector& stateUpdates, - const DefaultKeyedVector< wp, DisplayDeviceState>& displays, - const Vector& changedDisplays, uint32_t flags); + const DefaultKeyedVector, DisplayDeviceState>& displays, + const Vector& changedDisplays, uint32_t flags) override; // Intercept surface data - void saveSurfaceCreation(const sp& layer); - void saveSurfaceDeletion(const sp& layer); + void saveSurfaceCreation(const sp& layer) override; + void saveSurfaceDeletion(const sp& layer) override; void saveBufferUpdate(const sp& layer, uint32_t width, uint32_t height, - uint64_t frameNumber); + uint64_t frameNumber) override; // Intercept display data - void saveDisplayCreation(const DisplayDeviceState& info); - void saveDisplayDeletion(int32_t displayId); - void savePowerModeUpdate(int32_t displayId, int32_t mode); - void saveVSyncEvent(nsecs_t timestamp); + void saveDisplayCreation(const DisplayDeviceState& info) override; + void saveDisplayDeletion(int32_t displayId) override; + void savePowerModeUpdate(int32_t displayId, int32_t mode) override; + void saveVSyncEvent(nsecs_t timestamp) override; private: // The creation increments of Surfaces and Displays do not contain enough information to capture @@ -134,6 +175,7 @@ private: SurfaceFlinger* const mFlinger; }; -} +} // namespace impl +} // namespace android #endif // ANDROID_SURFACEINTERCEPTOR_H -- cgit v1.2.3-59-g8ed1b From 34beb7a0ff0494b0c5ad81104171f8a49e599163 Mon Sep 17 00:00:00 2001 From: Peiyong Lin Date: Wed, 28 Mar 2018 11:57:12 -0700 Subject: [SurfaceFlinger] Replace android_dataspace with Dataspace. This patch replaces all android_dataspace in SurfaceFlinger with Dataspace V1.1. 3 commands in sequence are used to do the conversion: find ./ -type f -exec sed -i -e 's/android_dataspace_t/Dataspace/g' {} \; find ./ -type f -exec sed -i -e 's/android_dataspace/Dataspace/g' {} \; find ./ -type f -exec sed -i -e 's/HAL_DATASPACE_/Dataspace::/g' {} \; With some minor tweak because most of the APIs in frameworks/native are still accepting android_dataspace/android_dataspace_t. Next step is to convert the rest of android_dataspace usage to Dataspace in frameworks/native as well as frameworks/base. BUG: 77156734 Test: Build and flash Change-Id: I2304c7014cb49a1c9f67c4563603fb55e8dbd679 --- libs/gui/Surface.cpp | 15 +-- libs/gui/include/gui/Surface.h | 9 +- libs/ui/include/ui/GraphicTypes.h | 2 + services/surfaceflinger/BufferLayer.cpp | 2 +- services/surfaceflinger/BufferLayerConsumer.cpp | 6 +- services/surfaceflinger/BufferLayerConsumer.h | 5 +- services/surfaceflinger/DisplayDevice.cpp | 9 +- services/surfaceflinger/DisplayDevice.h | 2 +- .../surfaceflinger/DisplayHardware/ComposerHal.cpp | 40 +++++--- .../surfaceflinger/DisplayHardware/ComposerHal.h | 5 +- .../DisplayHardware/FramebufferSurface.cpp | 11 ++- .../DisplayHardware/FramebufferSurface.h | 4 +- services/surfaceflinger/DisplayHardware/HWC2.cpp | 23 +++-- services/surfaceflinger/DisplayHardware/HWC2.h | 8 +- .../surfaceflinger/DisplayHardware/HWComposer.cpp | 4 +- .../surfaceflinger/DisplayHardware/HWComposer.h | 4 +- .../DisplayHardware/VirtualDisplaySurface.cpp | 2 +- services/surfaceflinger/Layer.cpp | 10 +- services/surfaceflinger/Layer.h | 6 +- .../RenderEngine/GLES20RenderEngine.cpp | 22 +++-- .../RenderEngine/GLES20RenderEngine.h | 8 +- .../surfaceflinger/RenderEngine/RenderEngine.h | 4 +- services/surfaceflinger/SurfaceFlinger.cpp | 62 ++++++------ services/surfaceflinger/SurfaceFlinger.h | 4 +- services/surfaceflinger/tests/hwc2/Android.bp | 1 + services/surfaceflinger/tests/hwc2/Hwc2Test.cpp | 19 ++-- .../tests/hwc2/Hwc2TestClientTarget.cpp | 2 +- .../tests/hwc2/Hwc2TestClientTarget.h | 2 +- .../surfaceflinger/tests/hwc2/Hwc2TestLayer.cpp | 2 +- services/surfaceflinger/tests/hwc2/Hwc2TestLayer.h | 2 +- .../surfaceflinger/tests/hwc2/Hwc2TestLayers.cpp | 2 +- .../surfaceflinger/tests/hwc2/Hwc2TestLayers.h | 2 +- .../tests/hwc2/Hwc2TestProperties.cpp | 106 ++++++++++----------- .../surfaceflinger/tests/hwc2/Hwc2TestProperties.h | 9 +- .../surfaceflinger/tests/unittests/MockComposer.h | 4 +- .../tests/unittests/MockRenderEngine.h | 4 +- 36 files changed, 226 insertions(+), 196 deletions(-) (limited to 'services/surfaceflinger/BufferLayer.cpp') diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 6a1aebd6d6..339bd0fa4e 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -45,6 +45,7 @@ namespace android { using ui::ColorMode; +using ui::Dataspace; Surface::Surface(const sp& bufferProducer, bool controlledByApp) : mGraphicBufferProducer(bufferProducer), @@ -80,7 +81,7 @@ Surface::Surface(const sp& bufferProducer, bool controll mReqFormat = 0; mReqUsage = 0; mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO; - mDataSpace = HAL_DATASPACE_UNKNOWN; + mDataSpace = Dataspace::UNKNOWN; mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE; mTransform = 0; mStickyTransform = 0; @@ -666,8 +667,9 @@ int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) { sp fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE); IGraphicBufferProducer::QueueBufferOutput output; IGraphicBufferProducer::QueueBufferInput input(timestamp, isAutoTimestamp, - mDataSpace, crop, mScalingMode, mTransform ^ mStickyTransform, - fence, mStickyTransform, mEnableFrameTimestamps); + static_cast(mDataSpace), crop, mScalingMode, + mTransform ^ mStickyTransform, fence, mStickyTransform, + mEnableFrameTimestamps); // we should send HDR metadata as needed if this becomes a bottleneck input.setHdrMetadata(mHdrMetadata); @@ -1098,8 +1100,7 @@ int Surface::dispatchSetSidebandStream(va_list args) { } int Surface::dispatchSetBuffersDataSpace(va_list args) { - android_dataspace dataspace = - static_cast(va_arg(args, int)); + Dataspace dataspace = static_cast(va_arg(args, int)); return setBuffersDataSpace(dataspace); } @@ -1531,7 +1532,7 @@ int Surface::setBuffersTimestamp(int64_t timestamp) return NO_ERROR; } -int Surface::setBuffersDataSpace(android_dataspace dataSpace) +int Surface::setBuffersDataSpace(Dataspace dataSpace) { ALOGV("Surface::setBuffersDataSpace"); Mutex::Autolock lock(mMutex); @@ -1563,7 +1564,7 @@ int Surface::setBuffersCta8613Metadata(const android_cta861_3_metadata* metadata return NO_ERROR; } -android_dataspace_t Surface::getBuffersDataSpace() { +Dataspace Surface::getBuffersDataSpace() { ALOGV("Surface::getBuffersDataSpace"); Mutex::Autolock lock(mMutex); return mDataSpace; diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h index 641d62cd4d..9aeafae198 100644 --- a/libs/gui/include/gui/Surface.h +++ b/libs/gui/include/gui/Surface.h @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -245,7 +246,7 @@ protected: virtual int setBuffersTransform(uint32_t transform); virtual int setBuffersStickyTransform(uint32_t transform); virtual int setBuffersTimestamp(int64_t timestamp); - virtual int setBuffersDataSpace(android_dataspace dataSpace); + virtual int setBuffersDataSpace(ui::Dataspace dataSpace); virtual int setBuffersSmpte2086Metadata(const android_smpte2086_metadata* metadata); virtual int setBuffersCta8613Metadata(const android_cta861_3_metadata* metadata); virtual int setCrop(Rect const* rect); @@ -286,7 +287,7 @@ public: // detachNextBuffer, or attachBuffer call. status_t getAndFlushRemovedBuffers(std::vector>* out); - android_dataspace_t getBuffersDataSpace(); + ui::Dataspace getBuffersDataSpace(); static status_t attachAndQueueBuffer(Surface* surface, sp buffer); @@ -340,9 +341,9 @@ protected: int64_t mTimestamp; // mDataSpace is the buffer dataSpace that will be used for the next buffer - // queue operation. It defaults to HAL_DATASPACE_UNKNOWN, which + // queue operation. It defaults to Dataspace::UNKNOWN, which // means that the buffer contains some type of color data. - android_dataspace mDataSpace; + ui::Dataspace mDataSpace; // mHdrMetadata is the HDR metadata that will be used for the next buffer // queue operation. There is no HDR metadata by default. diff --git a/libs/ui/include/ui/GraphicTypes.h b/libs/ui/include/ui/GraphicTypes.h index 39893b268a..92a5519898 100644 --- a/libs/ui/include/ui/GraphicTypes.h +++ b/libs/ui/include/ui/GraphicTypes.h @@ -25,6 +25,8 @@ namespace android { namespace ui { using android::hardware::graphics::common::V1_0::ColorMode; +using android::hardware::graphics::common::V1_1::Dataspace; +using android::hardware::graphics::common::V1_1::PixelFormat; } // namespace ui } // namespace android diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index 9200207f4a..82300e679f 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -829,7 +829,7 @@ void BufferLayer::drawWithOpenGL(const RenderArea& renderArea, bool useIdentityT getColor()); engine.setSourceDataSpace(mCurrentState.dataSpace); - if (mCurrentState.dataSpace == HAL_DATASPACE_BT2020_ITU_PQ && + if (mCurrentState.dataSpace == ui::Dataspace::BT2020_ITU_PQ && mConsumer->getCurrentApi() == NATIVE_WINDOW_API_MEDIA && getBE().compositionInfo.mBuffer->getPixelFormat() == HAL_PIXEL_FORMAT_RGBA_1010102) { engine.setSourceY410BT2020(true); diff --git a/services/surfaceflinger/BufferLayerConsumer.cpp b/services/surfaceflinger/BufferLayerConsumer.cpp index 46ec0e322b..6b4f5dbfb0 100644 --- a/services/surfaceflinger/BufferLayerConsumer.cpp +++ b/services/surfaceflinger/BufferLayerConsumer.cpp @@ -65,7 +65,7 @@ BufferLayerConsumer::BufferLayerConsumer(const sp& bq, mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), mCurrentFence(Fence::NO_FENCE), mCurrentTimestamp(0), - mCurrentDataSpace(HAL_DATASPACE_UNKNOWN), + mCurrentDataSpace(ui::Dataspace::UNKNOWN), mCurrentFrameNumber(0), mCurrentTransformToDisplayInverse(false), mCurrentSurfaceDamage(), @@ -341,7 +341,7 @@ status_t BufferLayerConsumer::updateAndReleaseLocked(const BufferItem& item, mCurrentTransform = item.mTransform; mCurrentScalingMode = item.mScalingMode; mCurrentTimestamp = item.mTimestamp; - mCurrentDataSpace = item.mDataSpace; + mCurrentDataSpace = static_cast(item.mDataSpace); mCurrentHdrMetadata = item.mHdrMetadata; mCurrentFence = item.mFence; mCurrentFenceTime = item.mFenceTime; @@ -445,7 +445,7 @@ nsecs_t BufferLayerConsumer::getTimestamp() { return mCurrentTimestamp; } -android_dataspace BufferLayerConsumer::getCurrentDataSpace() { +ui::Dataspace BufferLayerConsumer::getCurrentDataSpace() { BLC_LOGV("getCurrentDataSpace"); Mutex::Autolock lock(mMutex); return mCurrentDataSpace; diff --git a/services/surfaceflinger/BufferLayerConsumer.h b/services/surfaceflinger/BufferLayerConsumer.h index 11048d8df8..f81cdb1d91 100644 --- a/services/surfaceflinger/BufferLayerConsumer.h +++ b/services/surfaceflinger/BufferLayerConsumer.h @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -122,7 +123,7 @@ public: // getDataSpace retrieves the DataSpace associated with the texture image // set by the most recent call to updateTexImage. - android_dataspace getCurrentDataSpace(); + ui::Dataspace getCurrentDataSpace(); // getCurrentHdrMetadata retrieves the HDR metadata associated with the // texture image set by the most recent call to updateTexImage. @@ -324,7 +325,7 @@ private: // mCurrentDataSpace is the dataspace for the current texture. It // gets set each time updateTexImage is called. - android_dataspace mCurrentDataSpace; + ui::Dataspace mCurrentDataSpace; // mCurrentHdrMetadata is the HDR metadata for the current texture. It // gets set each time updateTexImage is called. diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp index 8281ce0f56..58a774b7e2 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -278,9 +278,9 @@ android_color_transform_t DisplayDevice::getColorTransform() const { return mColorTransform; } -void DisplayDevice::setCompositionDataSpace(android_dataspace dataspace) { +void DisplayDevice::setCompositionDataSpace(ui::Dataspace dataspace) { ANativeWindow* const window = mNativeWindow.get(); - native_window_set_buffers_data_space(window, dataspace); + native_window_set_buffers_data_space(window, static_cast(dataspace)); } // ---------------------------------------------------------------------------- @@ -463,12 +463,11 @@ void DisplayDevice::dump(String8& result) const { mScissor.top, mScissor.right, mScissor.bottom, tr[0][0], tr[1][0], tr[2][0], tr[0][1], tr[1][1], tr[2][1], tr[0][2], tr[1][2], tr[2][2]); auto const surface = static_cast(window); - android_dataspace dataspace = surface->getBuffersDataSpace(); + ui::Dataspace dataspace = surface->getBuffersDataSpace(); result.appendFormat(" wideColor=%d, hdr=%d, colorMode=%s, dataspace: %s (%d)\n", mDisplayHasWideColor, mDisplayHasHdr, decodeColorMode(mActiveColorMode).c_str(), - dataspaceDetails(dataspace).c_str(), dataspace); - + dataspaceDetails(static_cast(dataspace)).c_str(), dataspace); String8 surfaceDump; mDisplaySurface->dumpAsString(surfaceDump); diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h index 31bb4d0778..e844d115c2 100644 --- a/services/surfaceflinger/DisplayDevice.h +++ b/services/surfaceflinger/DisplayDevice.h @@ -167,7 +167,7 @@ public: void setActiveColorMode(ui::ColorMode mode); android_color_transform_t getColorTransform() const; void setColorTransform(const mat4& transform); - void setCompositionDataSpace(android_dataspace dataspace); + void setCompositionDataSpace(ui::Dataspace dataspace); /* ------------------------------------------------------------------------ * Display active config management. diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp index 117a99db79..bbffd0ae7f 100644 --- a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp +++ b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp @@ -32,6 +32,7 @@ namespace android { using hardware::Return; using hardware::hidl_vec; using hardware::hidl_handle; +using namespace hardware::graphics::common; using namespace hardware::graphics::composer; using PerFrameMetadata = hardware::graphics::composer::V2_2::IComposerClient::PerFrameMetadata; using PerFrameMetadataKey = @@ -256,17 +257,32 @@ Error Composer::createVirtualDisplay(uint32_t width, uint32_t height, { const uint32_t bufferSlotCount = 1; Error error = kDefaultError; - mClient->createVirtualDisplay(width, height, *format, bufferSlotCount, - [&](const auto& tmpError, const auto& tmpDisplay, - const auto& tmpFormat) { - error = tmpError; - if (error != Error::NONE) { - return; - } - - *outDisplay = tmpDisplay; - *format = tmpFormat; + if (mClient_2_2) { + mClient_2_2->createVirtualDisplay_2_2(width, height, *format, bufferSlotCount, + [&](const auto& tmpError, const auto& tmpDisplay, + const auto& tmpFormat) { + error = tmpError; + if (error != Error::NONE) { + return; + } + + *outDisplay = tmpDisplay; + *format = tmpFormat; + }); + } else { + mClient->createVirtualDisplay(width, height, + static_cast(*format), bufferSlotCount, + [&](const auto& tmpError, const auto& tmpDisplay, + const auto& tmpFormat) { + error = tmpError; + if (error != Error::NONE) { + return; + } + + *outDisplay = tmpDisplay; + *format = static_cast(tmpFormat); }); + } return error; } @@ -522,7 +538,7 @@ Error Composer::setClientTarget(Display display, uint32_t slot, .height = target->getHeight(), .stride = target->getStride(), .layerCount = target->getLayerCount(), - .format = static_cast(target->getPixelFormat()), + .format = static_cast(target->getPixelFormat()), .usage = target->getUsage(), }; mWriter.setClientTargetMetadata(metadata); @@ -645,7 +661,7 @@ Error Composer::setLayerBuffer(Display display, Layer layer, .height = buffer->getHeight(), .stride = buffer->getStride(), .layerCount = buffer->getLayerCount(), - .format = static_cast(buffer->getPixelFormat()), + .format = static_cast(buffer->getPixelFormat()), .usage = buffer->getUsage(), }; mWriter.setLayerBufferMetadata(metadata); diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h index c0373aa6c1..98f2f9d387 100644 --- a/services/surfaceflinger/DisplayHardware/ComposerHal.h +++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -39,10 +40,10 @@ using android::frameworks::vr::composer::V1_0::IVrComposerClient; using android::hardware::graphics::common::V1_0::ColorMode; using android::hardware::graphics::common::V1_0::ColorTransform; -using android::hardware::graphics::common::V1_0::Dataspace; using android::hardware::graphics::common::V1_0::Hdr; -using android::hardware::graphics::common::V1_0::PixelFormat; using android::hardware::graphics::common::V1_0::Transform; +using android::hardware::graphics::common::V1_1::Dataspace; +using android::hardware::graphics::common::V1_1::PixelFormat; using android::hardware::graphics::composer::V2_1::Config; using android::hardware::graphics::composer::V2_1::Display; diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp index 9398bdec92..e6d783434a 100644 --- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp +++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp @@ -44,6 +44,8 @@ namespace android { // ---------------------------------------------------------------------------- +using ui::Dataspace; + /* * This implements the (main) framebuffer management. This class is used * mostly by SurfaceFlinger, but also by command line GL application. @@ -92,7 +94,7 @@ status_t FramebufferSurface::advanceFrame() { uint32_t slot = 0; sp buf; sp acquireFence(Fence::NO_FENCE); - android_dataspace_t dataspace = HAL_DATASPACE_UNKNOWN; + Dataspace dataspace = Dataspace::UNKNOWN; status_t result = nextBuffer(slot, buf, acquireFence, dataspace); mDataSpace = dataspace; if (result != NO_ERROR) { @@ -104,7 +106,7 @@ status_t FramebufferSurface::advanceFrame() { status_t FramebufferSurface::nextBuffer(uint32_t& outSlot, sp& outBuffer, sp& outFence, - android_dataspace_t& outDataspace) { + Dataspace& outDataspace) { Mutex::Autolock lock(mMutex); BufferItem item; @@ -139,7 +141,7 @@ status_t FramebufferSurface::nextBuffer(uint32_t& outSlot, outFence = item.mFence; mHwcBufferCache.getHwcBuffer(mCurrentBufferSlot, mCurrentBuffer, &outSlot, &outBuffer); - outDataspace = item.mDataSpace; + outDataspace = static_cast(item.mDataSpace); status_t result = mHwc.setClientTarget(mDisplayType, outSlot, outFence, outBuffer, outDataspace); if (result != NO_ERROR) { @@ -178,7 +180,8 @@ void FramebufferSurface::onFrameCommitted() { void FramebufferSurface::dumpAsString(String8& result) const { Mutex::Autolock lock(mMutex); result.appendFormat(" FramebufferSurface: dataspace: %s(%d)\n", - dataspaceDetails(mDataSpace).c_str(), mDataSpace); + dataspaceDetails(static_cast(mDataSpace)).c_str(), + mDataSpace); ConsumerBase::dumpLocked(result, " "); } diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h index ed756c49a1..0fd8e9eaa4 100644 --- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h +++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h @@ -61,7 +61,7 @@ private: // BufferQueue and releases the previously latched buffer to the // BufferQueue. The new buffer is returned in the 'buffer' argument. status_t nextBuffer(uint32_t& outSlot, sp& outBuffer, - sp& outFence, android_dataspace_t& outDataspace); + sp& outFence, ui::Dataspace& outDataspace); // mDisplayType must match one of the HWC display types int mDisplayType; @@ -76,7 +76,7 @@ private: // compositing. Otherwise it will display the dataspace of the buffer // use for compositing which can change as wide-color content is // on/off. - android_dataspace mDataSpace; + ui::Dataspace mDataSpace; // mCurrentBuffer is the current buffer or nullptr to indicate that there is // no current buffer. diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp index c2425cee74..2686788ade 100644 --- a/services/surfaceflinger/DisplayHardware/HWC2.cpp +++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp @@ -47,6 +47,9 @@ using android::hardware::Void; namespace HWC2 { namespace Hwc2 = android::Hwc2; +using android::ui::ColorMode; +using android::ui::Dataspace; +using android::ui::PixelFormat; namespace { @@ -114,14 +117,13 @@ uint32_t Device::getMaxVirtualDisplayCount() const } Error Device::createVirtualDisplay(uint32_t width, uint32_t height, - android_pixel_format_t* format, Display** outDisplay) + PixelFormat* format, Display** outDisplay) { ALOGI("Creating virtual display"); hwc2_display_t displayId = 0; - auto intFormat = static_cast(*format); auto intError = mComposer->createVirtualDisplay(width, height, - &intFormat, &displayId); + format, &displayId); auto error = static_cast(intError); if (error != Error::None) { return error; @@ -131,7 +133,6 @@ Error Device::createVirtualDisplay(uint32_t width, uint32_t height, *mComposer.get(), mCapabilities, displayId, DisplayType::Virtual); display->setConnected(true); *outDisplay = display.get(); - *format = static_cast(intFormat); mDisplays.emplace(displayId, std::move(display)); ALOGI("Created virtual display"); return Error::None; @@ -362,7 +363,7 @@ Error Display::getChangedCompositionTypes( return Error::None; } -Error Display::getColorModes(std::vector* outModes) const +Error Display::getColorModes(std::vector* outModes) const { auto intError = mComposer.getColorModes(mId, outModes); return static_cast(intError); @@ -516,17 +517,16 @@ Error Display::setActiveConfig(const std::shared_ptr& config) } Error Display::setClientTarget(uint32_t slot, const sp& target, - const sp& acquireFence, android_dataspace_t dataspace) + const sp& acquireFence, Dataspace dataspace) { // TODO: Properly encode client target surface damage int32_t fenceFd = acquireFence->dup(); auto intError = mComposer.setClientTarget(mId, slot, target, - fenceFd, static_cast(dataspace), - std::vector()); + fenceFd, dataspace, std::vector()); return static_cast(intError); } -Error Display::setColorMode(android::ui::ColorMode mode) +Error Display::setColorMode(ColorMode mode) { auto intError = mComposer.setColorMode(mId, mode); return static_cast(intError); @@ -765,14 +765,13 @@ Error Layer::setCompositionType(Composition type) return static_cast(intError); } -Error Layer::setDataspace(android_dataspace_t dataspace) +Error Layer::setDataspace(Dataspace dataspace) { if (dataspace == mDataSpace) { return Error::None; } mDataSpace = dataspace; - auto intDataspace = static_cast(dataspace); - auto intError = mComposer.setLayerDataspace(mDisplayId, mId, intDataspace); + auto intError = mComposer.setLayerDataspace(mDisplayId, mId, mDataSpace); return static_cast(intError); } diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h index 71c094a035..9b870e3ed9 100644 --- a/services/surfaceflinger/DisplayHardware/HWC2.h +++ b/services/surfaceflinger/DisplayHardware/HWC2.h @@ -96,7 +96,7 @@ public: uint32_t getMaxVirtualDisplayCount() const; Error createVirtualDisplay(uint32_t width, uint32_t height, - android_pixel_format_t* format, Display** outDisplay); + android::ui::PixelFormat* format, Display** outDisplay); void destroyDisplay(hwc2_display_t displayId); void onHotplug(hwc2_display_t displayId, Connection connection); @@ -234,7 +234,7 @@ public: [[clang::warn_unused_result]] Error setClientTarget( uint32_t slot, const android::sp& target, const android::sp& acquireFence, - android_dataspace_t dataspace); + android::ui::Dataspace dataspace); [[clang::warn_unused_result]] Error setColorMode( android::ui::ColorMode mode); [[clang::warn_unused_result]] Error setColorTransform( @@ -311,7 +311,7 @@ public: [[clang::warn_unused_result]] Error setColor(hwc_color_t color); [[clang::warn_unused_result]] Error setCompositionType(Composition type); [[clang::warn_unused_result]] Error setDataspace( - android_dataspace_t dataspace); + android::ui::Dataspace dataspace); [[clang::warn_unused_result]] Error setHdrMetadata(const android::HdrMetadata& metadata); [[clang::warn_unused_result]] Error setDisplayFrame( const android::Rect& frame); @@ -335,7 +335,7 @@ private: hwc2_display_t mDisplayId; hwc2_layer_t mId; - android_dataspace mDataSpace = HAL_DATASPACE_UNKNOWN; + android::ui::Dataspace mDataSpace = android::ui::Dataspace::UNKNOWN; android::HdrMetadata mHdrMetadata; std::function mLayerDestroyedListener; }; diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp index 6bf2ee9362..29e2727b3e 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -179,7 +179,7 @@ bool HWComposer::onVsync(hwc2_display_t displayId, int64_t timestamp, } status_t HWComposer::allocateVirtualDisplay(uint32_t width, uint32_t height, - android_pixel_format_t* format, int32_t *outId) { + ui::PixelFormat* format, int32_t *outId) { if (mRemainingHwcVirtualDisplays == 0) { ALOGE("allocateVirtualDisplay: No remaining virtual displays"); return NO_MEMORY; @@ -387,7 +387,7 @@ void HWComposer::setVsyncEnabled(int32_t displayId, HWC2::Vsync enabled) { status_t HWComposer::setClientTarget(int32_t displayId, uint32_t slot, const sp& acquireFence, const sp& target, - android_dataspace_t dataspace) { + ui::Dataspace dataspace) { if (!isValidDisplay(displayId)) { return BAD_INDEX; } diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h index 0366a0d164..6e2e156abd 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.h +++ b/services/surfaceflinger/DisplayHardware/HWComposer.h @@ -80,7 +80,7 @@ public: // Attempts to allocate a virtual display. If the virtual display is created // on the HWC device, outId will contain its HWC ID. status_t allocateVirtualDisplay(uint32_t width, uint32_t height, - android_pixel_format_t* format, int32_t* outId); + ui::PixelFormat* format, int32_t* outId); // Attempts to create a new layer on this display HWC2::Layer* createLayer(int32_t displayId); @@ -92,7 +92,7 @@ public: status_t setClientTarget(int32_t displayId, uint32_t slot, const sp& acquireFence, - const sp& target, android_dataspace_t dataspace); + const sp& target, ui::Dataspace dataspace); // Present layers to the display and read releaseFences. status_t presentAndGetReleaseFences(int32_t displayId); diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp index 3480b24390..9a2817dba1 100644 --- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp +++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp @@ -222,7 +222,7 @@ status_t VirtualDisplaySurface::advanceFrame() { // TODO: Correctly propagate the dataspace from GL composition result = mHwc.setClientTarget(mDisplayId, hwcSlot, mFbFence, - hwcBuffer, HAL_DATASPACE_UNKNOWN); + hwcBuffer, ui::Dataspace::UNKNOWN); } return result; diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 5c945edb5f..9d356d86c7 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -122,7 +122,7 @@ Layer::Layer(SurfaceFlinger* flinger, const sp& client, const String8& n mCurrentState.layerStack = 0; mCurrentState.sequence = 0; mCurrentState.requested = mCurrentState.active; - mCurrentState.dataSpace = HAL_DATASPACE_UNKNOWN; + mCurrentState.dataSpace = ui::Dataspace::UNKNOWN; mCurrentState.appId = 0; mCurrentState.type = 0; @@ -1327,7 +1327,7 @@ bool Layer::setLayerStack(uint32_t layerStack) { return true; } -bool Layer::setDataSpace(android_dataspace dataSpace) { +bool Layer::setDataSpace(ui::Dataspace dataSpace) { if (mCurrentState.dataSpace == dataSpace) return false; mCurrentState.sequence++; mCurrentState.dataSpace = dataSpace; @@ -1336,7 +1336,7 @@ bool Layer::setDataSpace(android_dataspace dataSpace) { return true; } -android_dataspace Layer::getDataSpace() const { +ui::Dataspace Layer::getDataSpace() const { return mCurrentState.dataSpace; } @@ -1432,7 +1432,7 @@ LayerDebugInfo Layer::getLayerDebugInfo() const { info.mColor = ds.color; info.mFlags = ds.flags; info.mPixelFormat = getPixelFormat(); - info.mDataSpace = getDataSpace(); + info.mDataSpace = static_cast(getDataSpace()); info.mMatrix[0][0] = ds.active.transform[0][0]; info.mMatrix[0][1] = ds.active.transform[0][1]; info.mMatrix[1][0] = ds.active.transform[1][0]; @@ -1895,7 +1895,7 @@ void Layer::writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet) layerInfo->set_is_opaque(isOpaque(state)); layerInfo->set_invalidate(contentDirty); - layerInfo->set_dataspace(dataspaceDetails(getDataSpace())); + layerInfo->set_dataspace(dataspaceDetails(static_cast(getDataSpace()))); layerInfo->set_pixel_format(decodePixelFormat(getPixelFormat())); LayerProtoHelper::writeToProto(getColor(), layerInfo->mutable_color()); LayerProtoHelper::writeToProto(state.color, layerInfo->mutable_requested_color()); diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 69ffb2018c..8d2a0488dc 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -207,7 +207,7 @@ public: // dependent. Region activeTransparentRegion; Region requestedTransparentRegion; - android_dataspace dataSpace; + ui::Dataspace dataSpace; int32_t appId; int32_t type; @@ -285,8 +285,8 @@ public: bool setTransparentRegionHint(const Region& transparent); bool setFlags(uint8_t flags, uint8_t mask); bool setLayerStack(uint32_t layerStack); - bool setDataSpace(android_dataspace dataSpace); - android_dataspace getDataSpace() const; + bool setDataSpace(ui::Dataspace dataSpace); + ui::Dataspace getDataSpace() const; uint32_t getLayerStack() const; void deferTransactionUntil(const sp& barrierHandle, uint64_t frameNumber); void deferTransactionUntil(const sp& barrierLayer, uint64_t frameNumber); diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp index ea7dc2f1fd..1eda900f47 100644 --- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp +++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp @@ -109,6 +109,8 @@ namespace RE { namespace impl { // --------------------------------------------------------------------------- +using ui::Dataspace; + GLES20RenderEngine::GLES20RenderEngine(uint32_t featureFlags) : mVpWidth(0), mVpHeight(0), mPlatformHasWideColor((featureFlags & WIDE_COLOR_SUPPORT) != 0) { glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize); @@ -214,11 +216,11 @@ void GLES20RenderEngine::setSourceY410BT2020(bool enable) { mState.setY410BT2020(enable); } -void GLES20RenderEngine::setSourceDataSpace(android_dataspace source) { +void GLES20RenderEngine::setSourceDataSpace(Dataspace source) { mDataSpace = source; } -void GLES20RenderEngine::setOutputDataSpace(android_dataspace dataspace) { +void GLES20RenderEngine::setOutputDataSpace(Dataspace dataspace) { mOutputDataSpace = dataspace; } @@ -301,14 +303,14 @@ void GLES20RenderEngine::drawMesh(const Mesh& mesh) { mesh.getByteStride(), mesh.getPositions()); // DISPLAY_P3 is the only supported wide color output - if (mPlatformHasWideColor && mOutputDataSpace == HAL_DATASPACE_DISPLAY_P3) { + if (mPlatformHasWideColor && mOutputDataSpace == Dataspace::DISPLAY_P3) { Description wideColorState = mState; - switch (int(mDataSpace)) { - case HAL_DATASPACE_DISPLAY_P3: + switch (mDataSpace) { + case Dataspace::DISPLAY_P3: // input matches output break; - case HAL_DATASPACE_BT2020_PQ: - case HAL_DATASPACE_BT2020_ITU_PQ: + case Dataspace::BT2020_PQ: + case Dataspace::BT2020_ITU_PQ: wideColorState.setColorMatrix(mState.getColorMatrix() * mBt2020ToDisplayP3); wideColorState.setInputTransferFunction(Description::TransferFunction::ST2084); wideColorState.setOutputTransferFunction(Description::TransferFunction::SRGB); @@ -317,7 +319,7 @@ void GLES20RenderEngine::drawMesh(const Mesh& mesh) { default: // treat all other dataspaces as sRGB wideColorState.setColorMatrix(mState.getColorMatrix() * mSrgbToDisplayP3); - if ((mDataSpace & HAL_DATASPACE_TRANSFER_MASK) == HAL_DATASPACE_TRANSFER_LINEAR) { + if ((mDataSpace & Dataspace::TRANSFER_MASK) & Dataspace::TRANSFER_LINEAR) { wideColorState.setInputTransferFunction(Description::TransferFunction::LINEAR); } else { wideColorState.setInputTransferFunction(Description::TransferFunction::SRGB); @@ -350,8 +352,8 @@ void GLES20RenderEngine::drawMesh(const Mesh& mesh) { void GLES20RenderEngine::dump(String8& result) { RenderEngine::dump(result); result.appendFormat("RenderEngine last dataspace conversion: (%s) to (%s)\n", - dataspaceDetails(mDataSpace).c_str(), - dataspaceDetails(mOutputDataSpace).c_str()); + dataspaceDetails(static_cast(mDataSpace)).c_str(), + dataspaceDetails(static_cast(mOutputDataSpace)).c_str()); } // --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h index db3f79281e..99da19d6b1 100644 --- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h +++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h @@ -73,14 +73,14 @@ protected: // Color management related functions and state void setSourceY410BT2020(bool enable) override; - void setSourceDataSpace(android_dataspace source) override; - void setOutputDataSpace(android_dataspace dataspace) override; + void setSourceDataSpace(ui::Dataspace source) override; + void setOutputDataSpace(ui::Dataspace dataspace) override; // Current dataspace of layer being rendered - android_dataspace mDataSpace = HAL_DATASPACE_UNKNOWN; + ui::Dataspace mDataSpace = ui::Dataspace::UNKNOWN; // Current output dataspace of the render engine - android_dataspace mOutputDataSpace = HAL_DATASPACE_UNKNOWN; + ui::Dataspace mOutputDataSpace = ui::Dataspace::UNKNOWN; // Currently only supporting sRGB, BT2020 and DisplayP3 color spaces const bool mPlatformHasWideColor = false; diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.h b/services/surfaceflinger/RenderEngine/RenderEngine.h index d1405740e6..f78b230778 100644 --- a/services/surfaceflinger/RenderEngine/RenderEngine.h +++ b/services/surfaceflinger/RenderEngine/RenderEngine.h @@ -119,8 +119,8 @@ public: // wide color support virtual void setSourceY410BT2020(bool enable) = 0; - virtual void setSourceDataSpace(android_dataspace source) = 0; - virtual void setOutputDataSpace(android_dataspace dataspace) = 0; + virtual void setSourceDataSpace(ui::Dataspace source) = 0; + virtual void setOutputDataSpace(ui::Dataspace dataspace) = 0; // drawing virtual void drawMesh(const Mesh& mesh) = 0; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index f7f5b58616..ea759588df 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -105,6 +105,7 @@ namespace android { using namespace android::hardware::configstore; using namespace android::hardware::configstore::V1_0; using ui::ColorMode; +using ui::Dataspace; namespace { class ConditionalLock { @@ -1837,7 +1838,7 @@ mat4 SurfaceFlinger::computeSaturationMatrix() const { // pickColorMode translates a given dataspace into the best available color mode. // Currently only support sRGB and Display-P3. -ColorMode SurfaceFlinger::pickColorMode(android_dataspace dataSpace) const { +ColorMode SurfaceFlinger::pickColorMode(Dataspace dataSpace) const { if (mForceNativeColorMode) { return ColorMode::NATIVE; } @@ -1845,47 +1846,48 @@ ColorMode SurfaceFlinger::pickColorMode(android_dataspace dataSpace) const { switch (dataSpace) { // treat Unknown as regular SRGB buffer, since that's what the rest of the // system expects. - case HAL_DATASPACE_UNKNOWN: - case HAL_DATASPACE_SRGB: - case HAL_DATASPACE_V0_SRGB: + case Dataspace::UNKNOWN: + case Dataspace::SRGB: + case Dataspace::V0_SRGB: return ColorMode::SRGB; break; - case HAL_DATASPACE_DISPLAY_P3: + case Dataspace::DISPLAY_P3: return ColorMode::DISPLAY_P3; break; default: // TODO (courtneygo): Do we want to assert an error here? - ALOGE("No color mode mapping for %s (%#x)", dataspaceDetails(dataSpace).c_str(), + ALOGE("No color mode mapping for %s (%#x)", + dataspaceDetails(static_cast(dataSpace)).c_str(), dataSpace); return ColorMode::SRGB; break; } } -android_dataspace SurfaceFlinger::bestTargetDataSpace( - android_dataspace a, android_dataspace b, bool hasHdr) const { +Dataspace SurfaceFlinger::bestTargetDataSpace( + Dataspace a, Dataspace b, bool hasHdr) const { // Only support sRGB and Display-P3 right now. - if (a == HAL_DATASPACE_DISPLAY_P3 || b == HAL_DATASPACE_DISPLAY_P3) { - return HAL_DATASPACE_DISPLAY_P3; + if (a == Dataspace::DISPLAY_P3 || b == Dataspace::DISPLAY_P3) { + return Dataspace::DISPLAY_P3; } - if (a == HAL_DATASPACE_V0_SCRGB_LINEAR || b == HAL_DATASPACE_V0_SCRGB_LINEAR) { - return HAL_DATASPACE_DISPLAY_P3; + if (a == Dataspace::V0_SCRGB_LINEAR || b == Dataspace::V0_SCRGB_LINEAR) { + return Dataspace::DISPLAY_P3; } - if (a == HAL_DATASPACE_V0_SCRGB || b == HAL_DATASPACE_V0_SCRGB) { - return HAL_DATASPACE_DISPLAY_P3; + if (a == Dataspace::V0_SCRGB || b == Dataspace::V0_SCRGB) { + return Dataspace::DISPLAY_P3; } if (!hasHdr) { - if (a == HAL_DATASPACE_BT2020_PQ || b == HAL_DATASPACE_BT2020_PQ) { - return HAL_DATASPACE_DISPLAY_P3; + if (a == Dataspace::BT2020_PQ || b == Dataspace::BT2020_PQ) { + return Dataspace::DISPLAY_P3; } - if (a == HAL_DATASPACE_BT2020_ITU_PQ || b == HAL_DATASPACE_BT2020_ITU_PQ) { - return HAL_DATASPACE_DISPLAY_P3; + if (a == Dataspace::BT2020_ITU_PQ || b == Dataspace::BT2020_ITU_PQ) { + return Dataspace::DISPLAY_P3; } } - return HAL_DATASPACE_V0_SRGB; + return Dataspace::V0_SRGB; } void SurfaceFlinger::setUpHWComposer() { @@ -1966,8 +1968,8 @@ void SurfaceFlinger::setUpHWComposer() { "display %zd: %d", displayId, result); } for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { - if ((layer->getDataSpace() == HAL_DATASPACE_BT2020_PQ || - layer->getDataSpace() == HAL_DATASPACE_BT2020_ITU_PQ) && + if ((layer->getDataSpace() == Dataspace::BT2020_PQ || + layer->getDataSpace() == Dataspace::BT2020_ITU_PQ) && !displayDevice->getHdrSupport()) { layer->forceClientComposition(hwcId); } @@ -1983,14 +1985,14 @@ void SurfaceFlinger::setUpHWComposer() { if (hasWideColorDisplay) { ColorMode newColorMode; - android_dataspace newDataSpace = HAL_DATASPACE_V0_SRGB; + Dataspace newDataSpace = Dataspace::V0_SRGB; for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { newDataSpace = bestTargetDataSpace(layer->getDataSpace(), newDataSpace, displayDevice->getHdrSupport()); ALOGV("layer: %s, dataspace: %s (%#x), newDataSpace: %s (%#x)", - layer->getName().string(), dataspaceDetails(layer->getDataSpace()).c_str(), - layer->getDataSpace(), dataspaceDetails(newDataSpace).c_str(), newDataSpace); + layer->getName().string(), dataspaceDetails(static_cast(layer->getDataSpace())).c_str(), + layer->getDataSpace(), dataspaceDetails(static_cast(newDataSpace)).c_str(), newDataSpace); } newColorMode = pickColorMode(newDataSpace); @@ -2268,7 +2270,7 @@ sp SurfaceFlinger::setupNewDisplayDeviceInternal( defaultColorMode = ColorMode::SRGB; } setActiveColorModeInternal(hw, defaultColorMode); - hw->setCompositionDataSpace(HAL_DATASPACE_UNKNOWN); + hw->setCompositionDataSpace(Dataspace::UNKNOWN); hw->setLayerStack(state.layerStack); hw->setProjection(state.orientation, state.viewport, state.frame); hw->setDisplayName(state.displayName); @@ -2371,7 +2373,7 @@ void SurfaceFlinger::processDisplayChangesLocked() { int intFormat = 0; status = state.surface->query(NATIVE_WINDOW_FORMAT, &intFormat); ALOGE_IF(status != NO_ERROR, "Unable to query format (%d)", status); - auto format = static_cast(intFormat); + auto format = static_cast(intFormat); getBE().mHwc->allocateVirtualDisplay(width, height, &format, &hwcId); } @@ -2832,10 +2834,10 @@ bool SurfaceFlinger::doComposeSurfaces(const sp& displayDev if (hasClientComposition) { ALOGV("hasClientComposition"); - android_dataspace outputDataspace = HAL_DATASPACE_UNKNOWN; + Dataspace outputDataspace = Dataspace::UNKNOWN; if (displayDevice->getWideColorSupport() && displayDevice->getActiveColorMode() == ColorMode::DISPLAY_P3) { - outputDataspace = HAL_DATASPACE_DISPLAY_P3; + outputDataspace = Dataspace::DISPLAY_P3; } getBE().mRenderEngine->setOutputDataSpace(outputDataspace); @@ -4802,10 +4804,10 @@ void SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea, ALOGE("Invalid crop rect: b = %d (> %d)", sourceCrop.bottom, raHeight); } - android_dataspace outputDataspace = HAL_DATASPACE_UNKNOWN; + Dataspace outputDataspace = Dataspace::UNKNOWN; if (renderArea.getWideColorSupport() && renderArea.getActiveColorMode() == ColorMode::DISPLAY_P3) { - outputDataspace = HAL_DATASPACE_DISPLAY_P3; + outputDataspace = Dataspace::DISPLAY_P3; } getBE().mRenderEngine->setOutputDataSpace(outputDataspace); diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index c7c308883b..23c9684227 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -636,8 +636,8 @@ private: // Given a dataSpace, returns the appropriate color_mode to use // to display that dataSpace. - ui::ColorMode pickColorMode(android_dataspace dataSpace) const; - android_dataspace bestTargetDataSpace(android_dataspace a, android_dataspace b, + ui::ColorMode pickColorMode(ui::Dataspace dataSpace) const; + ui::Dataspace bestTargetDataSpace(ui::Dataspace a, ui::Dataspace b, bool hasHdr) const; mat4 computeSaturationMatrix() const; diff --git a/services/surfaceflinger/tests/hwc2/Android.bp b/services/surfaceflinger/tests/hwc2/Android.bp index e980522702..6c0e4abcfe 100644 --- a/services/surfaceflinger/tests/hwc2/Android.bp +++ b/services/surfaceflinger/tests/hwc2/Android.bp @@ -42,6 +42,7 @@ cc_test { ], shared_libs: [ "android.hardware.graphics.common@1.0", + "android.hardware.graphics.common@1.1", "libcutils", "libEGL", "libGLESv2", diff --git a/services/surfaceflinger/tests/hwc2/Hwc2Test.cpp b/services/surfaceflinger/tests/hwc2/Hwc2Test.cpp index b3f1b69f71..13774b4ed3 100644 --- a/services/surfaceflinger/tests/hwc2/Hwc2Test.cpp +++ b/services/surfaceflinger/tests/hwc2/Hwc2Test.cpp @@ -36,6 +36,7 @@ #include "Hwc2TestVirtualDisplay.h" using android::ui::ColorMode; +using android::ui::Dataspace; void hwc2TestHotplugCallback(hwc2_callback_data_t callbackData, hwc2_display_t display, int32_t connected); @@ -442,14 +443,14 @@ public: } void setLayerDataspace(hwc2_display_t display, hwc2_layer_t layer, - android_dataspace_t dataspace, hwc2_error_t* outErr = nullptr) + Dataspace dataspace, hwc2_error_t* outErr = nullptr) { auto pfn = reinterpret_cast( getFunction(HWC2_FUNCTION_SET_LAYER_DATASPACE)); ASSERT_TRUE(pfn) << "failed to get function"; auto err = static_cast(pfn(mHwc2Device, display, - layer, dataspace)); + layer, static_cast(dataspace))); if (outErr) { *outErr = err; } else { @@ -790,14 +791,14 @@ public: void getClientTargetSupport(hwc2_display_t display, int32_t width, int32_t height, android_pixel_format_t format, - android_dataspace_t dataspace, hwc2_error_t* outErr = nullptr) + Dataspace dataspace, hwc2_error_t* outErr = nullptr) { auto pfn = reinterpret_cast( getFunction(HWC2_FUNCTION_GET_CLIENT_TARGET_SUPPORT)); ASSERT_TRUE(pfn) << "failed to get function"; auto err = static_cast(pfn(mHwc2Device, display, width, - height, format, dataspace)); + height, format, static_cast(dataspace))); if (outErr) { *outErr = err; } else { @@ -807,7 +808,7 @@ public: } void setClientTarget(hwc2_display_t display, buffer_handle_t handle, - int32_t acquireFence, android_dataspace_t dataspace, + int32_t acquireFence, Dataspace dataspace, hwc_region_t damage, hwc2_error_t* outErr = nullptr) { auto pfn = reinterpret_cast( @@ -815,7 +816,7 @@ public: ASSERT_TRUE(pfn) << "failed to get function"; auto err = static_cast(pfn(mHwc2Device, display, handle, - acquireFence, dataspace, damage)); + acquireFence, static_cast(dataspace), damage)); if (outErr) { *outErr = err; } else { @@ -1691,7 +1692,7 @@ protected: const std::set& clearLayers, bool flipClientTarget, const Area& displayArea) { - android_dataspace_t dataspace = HAL_DATASPACE_UNKNOWN; + Dataspace dataspace = Dataspace::UNKNOWN; hwc_region_t damage = { }; buffer_handle_t handle; int32_t acquireFence; @@ -3716,7 +3717,7 @@ TEST_F(Hwc2Test, GET_CLIENT_TARGET_SUPPORT_unsupported) * layer. */ TEST_F(Hwc2Test, SET_CLIENT_TARGET_basic) { - const android_dataspace_t dataspace = HAL_DATASPACE_UNKNOWN; + const Dataspace dataspace = Dataspace::UNKNOWN; const hwc_region_t damage = { }; const size_t layerCnt = 1; @@ -3795,7 +3796,7 @@ TEST_F(Hwc2Test, SET_CLIENT_TARGET_bad_display) std::set clientLayers; std::set flipClientTargetLayers; bool flipClientTarget = true; - const android_dataspace_t dataspace = HAL_DATASPACE_UNKNOWN; + const Dataspace dataspace = Dataspace::UNKNOWN; const hwc_region_t damage = { }; buffer_handle_t handle; int32_t acquireFence; diff --git a/services/surfaceflinger/tests/hwc2/Hwc2TestClientTarget.cpp b/services/surfaceflinger/tests/hwc2/Hwc2TestClientTarget.cpp index 69254921d4..14c60a7d26 100644 --- a/services/surfaceflinger/tests/hwc2/Hwc2TestClientTarget.cpp +++ b/services/surfaceflinger/tests/hwc2/Hwc2TestClientTarget.cpp @@ -91,7 +91,7 @@ Area Hwc2TestClientTargetSupport::getBufferArea() const return mBufferArea.get(); } -android_dataspace_t Hwc2TestClientTargetSupport::getDataspace() const +android::ui::Dataspace Hwc2TestClientTargetSupport::getDataspace() const { return mDataspace.get(); } diff --git a/services/surfaceflinger/tests/hwc2/Hwc2TestClientTarget.h b/services/surfaceflinger/tests/hwc2/Hwc2TestClientTarget.h index 3b47978bef..6f4090f321 100644 --- a/services/surfaceflinger/tests/hwc2/Hwc2TestClientTarget.h +++ b/services/surfaceflinger/tests/hwc2/Hwc2TestClientTarget.h @@ -53,7 +53,7 @@ public: bool advance(); Area getBufferArea() const; - android_dataspace_t getDataspace() const; + android::ui::Dataspace getDataspace() const; const hwc_region_t getSurfaceDamage() const; private: diff --git a/services/surfaceflinger/tests/hwc2/Hwc2TestLayer.cpp b/services/surfaceflinger/tests/hwc2/Hwc2TestLayer.cpp index 937fce28fb..c1c9cc8f5b 100644 --- a/services/surfaceflinger/tests/hwc2/Hwc2TestLayer.cpp +++ b/services/surfaceflinger/tests/hwc2/Hwc2TestLayer.cpp @@ -146,7 +146,7 @@ hwc_rect_t Hwc2TestLayer::getCursorPosition() const return mDisplayFrame.get(); } -android_dataspace_t Hwc2TestLayer::getDataspace() const +android::ui::Dataspace Hwc2TestLayer::getDataspace() const { return mDataspace.get(); } diff --git a/services/surfaceflinger/tests/hwc2/Hwc2TestLayer.h b/services/surfaceflinger/tests/hwc2/Hwc2TestLayer.h index 0e7dd228fb..29ae521804 100644 --- a/services/surfaceflinger/tests/hwc2/Hwc2TestLayer.h +++ b/services/surfaceflinger/tests/hwc2/Hwc2TestLayer.h @@ -54,7 +54,7 @@ public: hwc_color_t getColor() const; hwc2_composition_t getComposition() const; hwc_rect_t getCursorPosition() const; - android_dataspace_t getDataspace() const; + android::ui::Dataspace getDataspace() const; hwc_rect_t getDisplayFrame() const; float getPlaneAlpha() const; hwc_frect_t getSourceCrop() const; diff --git a/services/surfaceflinger/tests/hwc2/Hwc2TestLayers.cpp b/services/surfaceflinger/tests/hwc2/Hwc2TestLayers.cpp index 495ef79609..90127a1302 100644 --- a/services/surfaceflinger/tests/hwc2/Hwc2TestLayers.cpp +++ b/services/surfaceflinger/tests/hwc2/Hwc2TestLayers.cpp @@ -169,7 +169,7 @@ hwc_rect_t Hwc2TestLayers::getCursorPosition(hwc2_layer_t layer) const return mTestLayers.at(layer).getCursorPosition(); } -android_dataspace_t Hwc2TestLayers::getDataspace(hwc2_layer_t layer) const +android::ui::Dataspace Hwc2TestLayers::getDataspace(hwc2_layer_t layer) const { if (mTestLayers.count(layer) == 0) { []() { GTEST_FAIL(); }(); diff --git a/services/surfaceflinger/tests/hwc2/Hwc2TestLayers.h b/services/surfaceflinger/tests/hwc2/Hwc2TestLayers.h index d95a91f485..909dd486e8 100644 --- a/services/surfaceflinger/tests/hwc2/Hwc2TestLayers.h +++ b/services/surfaceflinger/tests/hwc2/Hwc2TestLayers.h @@ -63,7 +63,7 @@ public: hwc_color_t getColor(hwc2_layer_t layer) const; hwc2_composition_t getComposition(hwc2_layer_t layer) const; hwc_rect_t getCursorPosition(hwc2_layer_t layer) const; - android_dataspace_t getDataspace(hwc2_layer_t layer) const; + android::ui::Dataspace getDataspace(hwc2_layer_t layer) const; hwc_rect_t getDisplayFrame(hwc2_layer_t layer) const; android_pixel_format_t getFormat(hwc2_layer_t layer) const; float getPlaneAlpha(hwc2_layer_t layer) const; diff --git a/services/surfaceflinger/tests/hwc2/Hwc2TestProperties.cpp b/services/surfaceflinger/tests/hwc2/Hwc2TestProperties.cpp index 5b3bbeb708..c5b92d0664 100644 --- a/services/surfaceflinger/tests/hwc2/Hwc2TestProperties.cpp +++ b/services/surfaceflinger/tests/hwc2/Hwc2TestProperties.cpp @@ -262,62 +262,62 @@ Hwc2TestDataspace::Hwc2TestDataspace(Hwc2TestCoverage coverage) std::string Hwc2TestDataspace::dump() const { std::stringstream dmp; - dmp << "\tdataspace: " << get() << "\n"; + dmp << "\tdataspace: " << static_cast(get()) << "\n"; return dmp.str(); } -const std::vector Hwc2TestDataspace::defaultDataspaces = { - HAL_DATASPACE_UNKNOWN, -}; - -const std::vector Hwc2TestDataspace::basicDataspaces = { - HAL_DATASPACE_UNKNOWN, - HAL_DATASPACE_V0_SRGB, -}; - -const std::vector Hwc2TestDataspace::completeDataspaces = { - HAL_DATASPACE_UNKNOWN, - HAL_DATASPACE_ARBITRARY, - HAL_DATASPACE_STANDARD_SHIFT, - HAL_DATASPACE_STANDARD_MASK, - HAL_DATASPACE_STANDARD_UNSPECIFIED, - HAL_DATASPACE_STANDARD_BT709, - HAL_DATASPACE_STANDARD_BT601_625, - HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED, - HAL_DATASPACE_STANDARD_BT601_525, - HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED, - HAL_DATASPACE_STANDARD_BT2020, - HAL_DATASPACE_STANDARD_BT2020_CONSTANT_LUMINANCE, - HAL_DATASPACE_STANDARD_BT470M, - HAL_DATASPACE_STANDARD_FILM, - HAL_DATASPACE_TRANSFER_SHIFT, - HAL_DATASPACE_TRANSFER_MASK, - HAL_DATASPACE_TRANSFER_UNSPECIFIED, - HAL_DATASPACE_TRANSFER_LINEAR, - HAL_DATASPACE_TRANSFER_SRGB, - HAL_DATASPACE_TRANSFER_SMPTE_170M, - HAL_DATASPACE_TRANSFER_GAMMA2_2, - HAL_DATASPACE_TRANSFER_GAMMA2_8, - HAL_DATASPACE_TRANSFER_ST2084, - HAL_DATASPACE_TRANSFER_HLG, - HAL_DATASPACE_RANGE_SHIFT, - HAL_DATASPACE_RANGE_MASK, - HAL_DATASPACE_RANGE_UNSPECIFIED, - HAL_DATASPACE_RANGE_FULL, - HAL_DATASPACE_RANGE_LIMITED, - HAL_DATASPACE_SRGB_LINEAR, - HAL_DATASPACE_V0_SRGB_LINEAR, - HAL_DATASPACE_SRGB, - HAL_DATASPACE_V0_SRGB, - HAL_DATASPACE_JFIF, - HAL_DATASPACE_V0_JFIF, - HAL_DATASPACE_BT601_625, - HAL_DATASPACE_V0_BT601_625, - HAL_DATASPACE_BT601_525, - HAL_DATASPACE_V0_BT601_525, - HAL_DATASPACE_BT709, - HAL_DATASPACE_V0_BT709, - HAL_DATASPACE_DEPTH, +const std::vector Hwc2TestDataspace::defaultDataspaces = { + android::ui::Dataspace::UNKNOWN, +}; + +const std::vector Hwc2TestDataspace::basicDataspaces = { + android::ui::Dataspace::UNKNOWN, + android::ui::Dataspace::V0_SRGB, +}; + +const std::vector Hwc2TestDataspace::completeDataspaces = { + android::ui::Dataspace::UNKNOWN, + android::ui::Dataspace::ARBITRARY, + android::ui::Dataspace::STANDARD_SHIFT, + android::ui::Dataspace::STANDARD_MASK, + android::ui::Dataspace::STANDARD_UNSPECIFIED, + android::ui::Dataspace::STANDARD_BT709, + android::ui::Dataspace::STANDARD_BT601_625, + android::ui::Dataspace::STANDARD_BT601_625_UNADJUSTED, + android::ui::Dataspace::STANDARD_BT601_525, + android::ui::Dataspace::STANDARD_BT601_525_UNADJUSTED, + android::ui::Dataspace::STANDARD_BT2020, + android::ui::Dataspace::STANDARD_BT2020_CONSTANT_LUMINANCE, + android::ui::Dataspace::STANDARD_BT470M, + android::ui::Dataspace::STANDARD_FILM, + android::ui::Dataspace::TRANSFER_SHIFT, + android::ui::Dataspace::TRANSFER_MASK, + android::ui::Dataspace::TRANSFER_UNSPECIFIED, + android::ui::Dataspace::TRANSFER_LINEAR, + android::ui::Dataspace::TRANSFER_SRGB, + android::ui::Dataspace::TRANSFER_SMPTE_170M, + android::ui::Dataspace::TRANSFER_GAMMA2_2, + android::ui::Dataspace::TRANSFER_GAMMA2_8, + android::ui::Dataspace::TRANSFER_ST2084, + android::ui::Dataspace::TRANSFER_HLG, + android::ui::Dataspace::RANGE_SHIFT, + android::ui::Dataspace::RANGE_MASK, + android::ui::Dataspace::RANGE_UNSPECIFIED, + android::ui::Dataspace::RANGE_FULL, + android::ui::Dataspace::RANGE_LIMITED, + android::ui::Dataspace::SRGB_LINEAR, + android::ui::Dataspace::V0_SRGB_LINEAR, + android::ui::Dataspace::SRGB, + android::ui::Dataspace::V0_SRGB, + android::ui::Dataspace::JFIF, + android::ui::Dataspace::V0_JFIF, + android::ui::Dataspace::BT601_625, + android::ui::Dataspace::V0_BT601_625, + android::ui::Dataspace::BT601_525, + android::ui::Dataspace::V0_BT601_525, + android::ui::Dataspace::BT709, + android::ui::Dataspace::V0_BT709, + android::ui::Dataspace::DEPTH, }; diff --git a/services/surfaceflinger/tests/hwc2/Hwc2TestProperties.h b/services/surfaceflinger/tests/hwc2/Hwc2TestProperties.h index cb811e06e2..d7082f3cb5 100644 --- a/services/surfaceflinger/tests/hwc2/Hwc2TestProperties.h +++ b/services/surfaceflinger/tests/hwc2/Hwc2TestProperties.h @@ -20,6 +20,7 @@ #include #include +#include #include #define HWC2_INCLUDE_STRINGIFICATION @@ -229,16 +230,16 @@ protected: }; -class Hwc2TestDataspace : public Hwc2TestProperty { +class Hwc2TestDataspace : public Hwc2TestProperty { public: Hwc2TestDataspace(Hwc2TestCoverage coverage); std::string dump() const override; protected: - static const std::vector defaultDataspaces; - static const std::vector basicDataspaces; - static const std::vector completeDataspaces; + static const std::vector defaultDataspaces; + static const std::vector basicDataspaces; + static const std::vector completeDataspaces; static const std::array mCompositionSupport; }; diff --git a/services/surfaceflinger/tests/unittests/MockComposer.h b/services/surfaceflinger/tests/unittests/MockComposer.h index acd9b3099a..00e565b75c 100644 --- a/services/surfaceflinger/tests/unittests/MockComposer.h +++ b/services/surfaceflinger/tests/unittests/MockComposer.h @@ -29,10 +29,10 @@ namespace mock { using android::hardware::graphics::common::V1_0::ColorMode; using android::hardware::graphics::common::V1_0::ColorTransform; -using android::hardware::graphics::common::V1_0::Dataspace; using android::hardware::graphics::common::V1_0::Hdr; -using android::hardware::graphics::common::V1_0::PixelFormat; using android::hardware::graphics::common::V1_0::Transform; +using android::hardware::graphics::common::V1_1::Dataspace; +using android::hardware::graphics::common::V1_1::PixelFormat; using android::hardware::graphics::composer::V2_1::Config; using android::hardware::graphics::composer::V2_1::Display; diff --git a/services/surfaceflinger/tests/unittests/MockRenderEngine.h b/services/surfaceflinger/tests/unittests/MockRenderEngine.h index 6d3e17ff73..9bb2a3c961 100644 --- a/services/surfaceflinger/tests/unittests/MockRenderEngine.h +++ b/services/surfaceflinger/tests/unittests/MockRenderEngine.h @@ -64,8 +64,8 @@ public: MOCK_METHOD0(disableTexturing, void()); MOCK_METHOD0(disableBlending, void()); MOCK_METHOD1(setSourceY410BT2020, void(bool)); - MOCK_METHOD1(setSourceDataSpace, void(android_dataspace)); - MOCK_METHOD1(setOutputDataSpace, void(android_dataspace)); + MOCK_METHOD1(setSourceDataSpace, void(ui::Dataspace)); + MOCK_METHOD1(setOutputDataSpace, void(ui::Dataspace)); MOCK_METHOD2(bindNativeBufferAsFrameBuffer, void(ANativeWindowBuffer*, RE::BindNativeBufferAsFramebuffer*)); MOCK_METHOD1(unbindNativeBufferAsFrameBuffer, void(RE::BindNativeBufferAsFramebuffer*)); -- cgit v1.2.3-59-g8ed1b From 2713c30843816d3511b39b85a2c268a2b7682047 Mon Sep 17 00:00:00 2001 From: Dan Stoza Date: Wed, 28 Mar 2018 17:07:36 -0700 Subject: Early wake-up for transitions (1/2) On some devices it's very likely that we fall into GL comp during app transitions. However, SF offsets are chosen in a way such that the time to finish a frame is just too tight to be completely jank free when hitting GL composition in SurfaceFlinger. Thus, we introduce the concept of a separate early offset, and wakeup SurfaceFlinger at that time if we think that hitting GL comp is likely, or we already hit GL comp in the last frame. Test: Open app, check vsync offsets in systrace Test: Open many dialogs/apps to fall into GPU comp. Bug: 75985430 Change-Id: Ie17e30c4575359fa11bb8912f68dcafe3e569ddb Merged-In: Ie17e30c4575359fa11bb8912f68dcafe3e569ddb --- libs/gui/SurfaceComposerClient.cpp | 11 ++- libs/gui/include/gui/ISurfaceComposer.h | 5 + libs/gui/include/gui/SurfaceComposerClient.h | 2 + services/surfaceflinger/BufferLayer.cpp | 1 + services/surfaceflinger/BufferLayerConsumer.cpp | 1 + services/surfaceflinger/DispSync.cpp | 27 ++++++ services/surfaceflinger/DispSync.h | 5 + .../RenderEngine/GLES20RenderEngine.cpp | 1 + services/surfaceflinger/SurfaceFlinger.cpp | 41 +++++---- services/surfaceflinger/SurfaceFlinger.h | 6 ++ services/surfaceflinger/VSyncModulator.h | 101 +++++++++++++++++++++ 11 files changed, 184 insertions(+), 17 deletions(-) create mode 100644 services/surfaceflinger/VSyncModulator.h (limited to 'services/surfaceflinger/BufferLayer.cpp') diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index bbf681ea90..63560c4b89 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -101,7 +101,8 @@ void ComposerService::composerServiceDied() SurfaceComposerClient::Transaction::Transaction(const Transaction& other) : mForceSynchronous(other.mForceSynchronous), mTransactionNestCount(other.mTransactionNestCount), - mAnimation(other.mAnimation) { + mAnimation(other.mAnimation), + mEarlyWakeup(other.mEarlyWakeup) { mDisplayStates = other.mDisplayStates; mComposerStates = other.mComposerStates; } @@ -157,9 +158,13 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous) { if (mAnimation) { flags |= ISurfaceComposer::eAnimation; } + if (mEarlyWakeup) { + flags |= ISurfaceComposer::eEarlyWakeup; + } mForceSynchronous = false; mAnimation = false; + mEarlyWakeup = false; sf->setTransactionState(composerStates, displayStates, flags); mStatus = NO_ERROR; @@ -185,6 +190,10 @@ void SurfaceComposerClient::Transaction::setAnimationTransaction() { mAnimation = true; } +void SurfaceComposerClient::Transaction::setEarlyWakeup() { + mEarlyWakeup = true; +} + layer_state_t* SurfaceComposerClient::Transaction::getLayerState(const sp& sc) { if (mComposerStates.count(sc) == 0) { // we don't have it, add an initialized layer_state to our list diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h index 3591090172..e40157206d 100644 --- a/libs/gui/include/gui/ISurfaceComposer.h +++ b/libs/gui/include/gui/ISurfaceComposer.h @@ -61,6 +61,11 @@ public: enum { eSynchronous = 0x01, eAnimation = 0x02, + + // Indicates that this transaction will likely result in a lot of layers being composed, and + // thus, SurfaceFlinger should wake-up earlier to avoid missing frame deadlines. In this + // case SurfaceFlinger will wake up at (sf vsync offset - debug.sf.early_phase_offset_ns) + eEarlyWakeup = 0x04 }; enum { diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index ffc22f6437..377fe68c41 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -154,6 +154,7 @@ public: uint32_t mForceSynchronous = 0; uint32_t mTransactionNestCount = 0; bool mAnimation = false; + bool mEarlyWakeup = false; int mStatus = NO_ERROR; @@ -273,6 +274,7 @@ public: const Rect& displayRect); void setDisplaySize(const sp& token, uint32_t width, uint32_t height); void setAnimationTransaction(); + void setEarlyWakeup(); }; status_t destroySurface(const sp& id); diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index 82300e679f..2aa4cd3578 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -778,6 +778,7 @@ bool BufferLayer::getOpacityForFormat(uint32_t format) { } void BufferLayer::drawWithOpenGL(const RenderArea& renderArea, bool useIdentityTransform) const { + ATRACE_CALL(); const State& s(getDrawingState()); computeGeometry(renderArea, getBE().mMesh, useIdentityTransform); diff --git a/services/surfaceflinger/BufferLayerConsumer.cpp b/services/surfaceflinger/BufferLayerConsumer.cpp index 6b4f5dbfb0..87333d0ffd 100644 --- a/services/surfaceflinger/BufferLayerConsumer.cpp +++ b/services/surfaceflinger/BufferLayerConsumer.cpp @@ -356,6 +356,7 @@ status_t BufferLayerConsumer::updateAndReleaseLocked(const BufferItem& item, } status_t BufferLayerConsumer::bindTextureImageLocked() { + ATRACE_CALL(); mRE.checkErrors(); if (mCurrentTexture == BufferQueue::INVALID_BUFFER_SLOT && mCurrentTextureImage == nullptr) { diff --git a/services/surfaceflinger/DispSync.cpp b/services/surfaceflinger/DispSync.cpp index 9e01fd0d8d..7acbd11bc5 100644 --- a/services/surfaceflinger/DispSync.cpp +++ b/services/surfaceflinger/DispSync.cpp @@ -209,6 +209,28 @@ public: return BAD_VALUE; } + status_t changePhaseOffset(DispSync::Callback* callback, nsecs_t phase) { + if (kTraceDetailedInfo) ATRACE_CALL(); + Mutex::Autolock lock(mMutex); + + for (size_t i = 0; i < mEventListeners.size(); i++) { + if (mEventListeners[i].mCallback == callback) { + EventListener& listener = mEventListeners.editItemAt(i); + const nsecs_t oldPhase = listener.mPhase; + listener.mPhase = phase; + + // Pretend that the last time this event was handled at the same frame but with the + // new offset to allow for a seamless offset change without double-firing or + // skipping. + listener.mLastEventTime -= (oldPhase - phase); + mCond.signal(); + return NO_ERROR; + } + } + + return BAD_VALUE; + } + // This method is only here to handle the !SurfaceFlinger::hasSyncFramework // case. bool hasAnyEventListeners() { @@ -487,6 +509,11 @@ status_t DispSync::removeEventListener(Callback* callback) { return mThread->removeEventListener(callback); } +status_t DispSync::changePhaseOffset(Callback* callback, nsecs_t phase) { + Mutex::Autolock lock(mMutex); + return mThread->changePhaseOffset(callback, phase); +} + void DispSync::setPeriod(nsecs_t period) { Mutex::Autolock lock(mMutex); mPeriod = period; diff --git a/services/surfaceflinger/DispSync.h b/services/surfaceflinger/DispSync.h index 9336f4dd86..077256ac11 100644 --- a/services/surfaceflinger/DispSync.h +++ b/services/surfaceflinger/DispSync.h @@ -113,6 +113,11 @@ public: // DispSync object. status_t removeEventListener(Callback* callback); + // changePhaseOffset changes the phase offset of an already-registered event callback. The + // method will make sure that there is no skipping or double-firing on the listener per frame, + // even when changing the offsets multiple times. + status_t changePhaseOffset(Callback* callback, nsecs_t phase); + // computeNextRefresh computes when the next refresh is expected to begin. // The periodOffset value can be used to move forward or backward; an // offset of zero is the next refresh, -1 is the previous refresh, 1 is diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp index 1fc310025d..0fb3d28d05 100644 --- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp +++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp @@ -293,6 +293,7 @@ void GLES20RenderEngine::setupFillWithColor(float r, float g, float b, float a) } void GLES20RenderEngine::drawMesh(const Mesh& mesh) { + ATRACE_CALL(); if (mesh.getTexCoordsSize()) { glEnableVertexAttribArray(Program::texCoords); glVertexAttribPointer(Program::texCoords, mesh.getTexCoordsSize(), GL_FLOAT, GL_FALSE, diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 5be7951972..183c1eb07c 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -296,6 +296,12 @@ SurfaceFlinger::SurfaceFlinger() : SurfaceFlinger(SkipInitialization) { auto listSize = property_get_int32("debug.sf.max_igbp_list_size", int32_t(defaultListSize)); mMaxGraphicBufferProducerListSize = (listSize > 0) ? size_t(listSize) : defaultListSize; + property_get("debug.sf.early_phase_offset_ns", value, "0"); + const int earlyWakeupOffsetOffsetNs = atoi(value); + ALOGI_IF(earlyWakeupOffsetOffsetNs != 0, "Enabling separate early offset"); + mVsyncModulator.setPhaseOffsets(sfVsyncPhaseOffsetNs - earlyWakeupOffsetOffsetNs, + sfVsyncPhaseOffsetNs); + // We should be reading 'persist.sys.sf.color_saturation' here // but since /data may be encrypted, we need to wait until after vold // comes online to attempt to read the property. The property is @@ -522,19 +528,10 @@ public: return; } - // Remove the listener with the old offset - status_t err = mDispSync->removeEventListener( - static_cast(this)); + status_t err = mDispSync->changePhaseOffset(static_cast(this), + mPhaseOffset); if (err != NO_ERROR) { - ALOGE("error unregistering vsync callback: %s (%d)", - strerror(-err), err); - } - - // Add a listener with the new offset - err = mDispSync->addEventListener(mName, mPhaseOffset, - static_cast(this)); - if (err != NO_ERROR) { - ALOGE("error registering vsync callback: %s (%d)", + ALOGE("error changing vsync offset: %s (%d)", strerror(-err), err); } } @@ -623,6 +620,7 @@ void SurfaceFlinger::init() { mSFEventThread = std::make_unique(mSfEventThreadSource.get(), *this, true, "sfEventThread"); mEventQueue->setEventThread(mSFEventThread.get()); + mVsyncModulator.setEventThread(mSFEventThread.get()); // Get a RenderEngine for the given display / config (can't fail) getBE().mRenderEngine = @@ -1498,6 +1496,7 @@ void SurfaceFlinger::handleMessageRefresh() { mHadClientComposition = mHadClientComposition || getBE().mHwc->hasClientComposition(displayDevice->getHwcDisplayId()); } + mVsyncModulator.setLastFrameUsedRenderEngine(mHadClientComposition); mLayersWithQueuedFrames.clear(); } @@ -2122,6 +2121,7 @@ void SurfaceFlinger::handleTransaction(uint32_t transactionFlags) // with mStateLock held to guarantee that mCurrentState won't change // until the transaction is committed. + mVsyncModulator.setTransactionStart(VSyncModulator::TransactionStart::NORMAL); transactionFlags = getTransactionFlags(eTransactionMask); handleTransactionLocked(transactionFlags); @@ -3070,7 +3070,13 @@ uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) { } uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) { + return setTransactionFlags(flags, VSyncModulator::TransactionStart::NORMAL); +} + +uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags, + VSyncModulator::TransactionStart transactionStart) { uint32_t old = android_atomic_or(flags, &mTransactionFlags); + mVsyncModulator.setTransactionStart(transactionStart); if ((old & flags)==0) { // wake the server up signalTransaction(); } @@ -3159,7 +3165,10 @@ void SurfaceFlinger::setTransactionState( } // this triggers the transaction - setTransactionFlags(transactionFlags); + const auto start = (flags & eEarlyWakeup) + ? VSyncModulator::TransactionStart::EARLY + : VSyncModulator::TransactionStart::NORMAL; + setTransactionFlags(transactionFlags, start); // if this is a synchronous transaction, wait for it to take effect // before returning. @@ -4099,9 +4108,9 @@ void SurfaceFlinger::dumpAllLocked(const Vector& args, size_t& index, colorizer.bold(result); result.append("DispSync configuration: "); colorizer.reset(result); - result.appendFormat("app phase %" PRId64 " ns, sf phase %" PRId64 " ns, " - "present offset %" PRId64 " ns (refresh %" PRId64 " ns)", - vsyncPhaseOffsetNs, sfVsyncPhaseOffsetNs, + result.appendFormat("app phase %" PRId64 " ns, sf phase %" PRId64 " ns, early sf phase %" PRId64 + " ns, present offset %" PRId64 " ns (refresh %" PRId64 " ns)", + vsyncPhaseOffsetNs, sfVsyncPhaseOffsetNs, mVsyncModulator.getEarlyPhaseOffset(), dispSyncPresentTimeOffset, activeConfig->getVsyncPeriod()); result.append("\n"); diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 89c9cfda19..a29d1d7475 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -54,6 +55,7 @@ #include "Barrier.h" #include "DisplayDevice.h" #include "DispSync.h" +#include "EventThread.h" #include "FrameTracker.h" #include "LayerStats.h" #include "LayerVector.h" @@ -61,6 +63,7 @@ #include "SurfaceInterceptor.h" #include "SurfaceTracing.h" #include "StartPropertySetThread.h" +#include "VSyncModulator.h" #include "DisplayHardware/HWC2.h" #include "DisplayHardware/HWComposer.h" @@ -492,6 +495,7 @@ private: uint32_t peekTransactionFlags(); // Can only be called from the main thread or with mStateLock held uint32_t setTransactionFlags(uint32_t flags); + uint32_t setTransactionFlags(uint32_t flags, VSyncModulator::TransactionStart transactionStart); void commitTransaction(); bool containsAnyInvalidClientState(const Vector& states); uint32_t setClientStateLocked(const ComposerState& composerState); @@ -765,6 +769,8 @@ private: std::unique_ptr mEventControlThread; sp mBuiltinDisplays[DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES]; + VSyncModulator mVsyncModulator; + // Can only accessed from the main thread, these members // don't need synchronization State mDrawingState{LayerVector::StateSet::Drawing}; diff --git a/services/surfaceflinger/VSyncModulator.h b/services/surfaceflinger/VSyncModulator.h new file mode 100644 index 0000000000..3126debed4 --- /dev/null +++ b/services/surfaceflinger/VSyncModulator.h @@ -0,0 +1,101 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include + +using namespace android::surfaceflinger; + +namespace android { + +/* + * Modulates the vsync-offsets depending on current SurfaceFlinger state. + */ +class VSyncModulator { +public: + + enum TransactionStart { + EARLY, + NORMAL + }; + + // Sets the phase offsets + // + // early: the phase offset when waking up early. May be the same as late, in which case we don't + // shift offsets. + // late: the regular sf phase offset. + void setPhaseOffsets(nsecs_t early, nsecs_t late) { + mEarlyPhaseOffset = early; + mLatePhaseOffset = late; + mPhaseOffset = late; + } + + nsecs_t getEarlyPhaseOffset() const { + return mEarlyPhaseOffset; + } + + void setEventThread(EventThread* eventThread) { + mEventThread = eventThread; + } + + void setTransactionStart(TransactionStart transactionStart) { + if (transactionStart == mTransactionStart) return; + mTransactionStart = transactionStart; + updatePhaseOffsets(); + } + + void setLastFrameUsedRenderEngine(bool re) { + if (re == mLastFrameUsedRenderEngine) return; + mLastFrameUsedRenderEngine = re; + updatePhaseOffsets(); + } + +private: + + void updatePhaseOffsets() { + + // Do not change phase offsets if disabled. + if (mEarlyPhaseOffset == mLatePhaseOffset) return; + + if (mTransactionStart == TransactionStart::EARLY || mLastFrameUsedRenderEngine) { + if (mPhaseOffset != mEarlyPhaseOffset) { + if (mEventThread) { + mEventThread->setPhaseOffset(mEarlyPhaseOffset); + } + mPhaseOffset = mEarlyPhaseOffset; + } + } else { + if (mPhaseOffset != mLatePhaseOffset) { + if (mEventThread) { + mEventThread->setPhaseOffset(mLatePhaseOffset); + } + mPhaseOffset = mLatePhaseOffset; + } + } + } + + nsecs_t mLatePhaseOffset = 0; + nsecs_t mEarlyPhaseOffset = 0; + EventThread* mEventThread = nullptr; + std::atomic mPhaseOffset = 0; + std::atomic mTransactionStart = TransactionStart::NORMAL; + std::atomic mLastFrameUsedRenderEngine = false; +}; + +} // namespace android -- cgit v1.2.3-59-g8ed1b From 923e7c56cb9a4a611dcc3db904116926ee958ad7 Mon Sep 17 00:00:00 2001 From: Peiyong Lin Date: Mon, 16 Apr 2018 14:16:37 -0700 Subject: [SurfaceFlinger] Make sure data space is set correctly This patch makes sure data space is set correctly for native window. Previously, the data space could be unknown. BUG: 77652630 BUG: 78025830 Test: Build, flash, watch some videos Change-Id: I3096ebaecda35838493e0d5e2efdf141eff0b75e --- services/surfaceflinger/BufferLayer.cpp | 22 +++++++++++++++++++++- services/surfaceflinger/Layer.cpp | 14 ++------------ 2 files changed, 23 insertions(+), 13 deletions(-) (limited to 'services/surfaceflinger/BufferLayer.cpp') diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index 2aa4cd3578..57f474b9ea 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -515,7 +515,27 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime recomputeVisibleRegions = true; } - setDataSpace(mConsumer->getCurrentDataSpace()); + // Dataspace::V0_SRGB and Dataspace::V0_SRGB_LINEAR are not legacy + // data space, however since framework doesn't distinguish them out of + // legacy SRGB, we have to treat them as the same for now. + // UNKNOWN is treated as legacy SRGB when the connected api is EGL. + ui::Dataspace dataSpace = mConsumer->getCurrentDataSpace(); + switch (dataSpace) { + case ui::Dataspace::V0_SRGB: + dataSpace = ui::Dataspace::SRGB; + break; + case ui::Dataspace::V0_SRGB_LINEAR: + dataSpace = ui::Dataspace::SRGB_LINEAR; + break; + case ui::Dataspace::UNKNOWN: + if (mConsumer->getCurrentApi() == NATIVE_WINDOW_API_EGL) { + dataSpace = ui::Dataspace::SRGB; + } + break; + default: + break; + } + setDataSpace(dataSpace); Rect crop(mConsumer->getCurrentCrop()); const uint32_t transform(mConsumer->getCurrentTransform()); diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 8c0050ee47..3a71188b37 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -1643,19 +1643,9 @@ bool Layer::detachChildren() { return true; } -// Dataspace::UNKNOWN, Dataspace::SRGB, Dataspace::SRGB_LINEAR, -// Dataspace::V0_SRGB and Dataspace::V0_SRGB_LINEAR are considered legacy -// SRGB data space for now. -// Note that Dataspace::V0_SRGB and Dataspace::V0_SRGB_LINEAR are not legacy -// data space, however since framework doesn't distinguish them out of legacy -// SRGB, we have to treat them as the same for now. bool Layer::isLegacySrgbDataSpace() const { - // TODO(lpy) b/77652630, need to figure out when UNKNOWN can be treated as SRGB. - return mDrawingState.dataSpace == ui::Dataspace::UNKNOWN || - mDrawingState.dataSpace == ui::Dataspace::SRGB || - mDrawingState.dataSpace == ui::Dataspace::SRGB_LINEAR || - mDrawingState.dataSpace == ui::Dataspace::V0_SRGB || - mDrawingState.dataSpace == ui::Dataspace::V0_SRGB_LINEAR; + return mDrawingState.dataSpace == ui::Dataspace::SRGB || + mDrawingState.dataSpace == ui::Dataspace::SRGB_LINEAR; } void Layer::setParent(const sp& layer) { -- cgit v1.2.3-59-g8ed1b From 2c327ac2840b34848543cc961d16d3dbad102f16 Mon Sep 17 00:00:00 2001 From: Peiyong Lin Date: Thu, 19 Apr 2018 22:06:34 -0700 Subject: [SurfaceFlinger] Plumb getPerFrameMetadataKeys and setLayerPerFrameMetadata. This patch compresses supported metdata types into a bitmask and stores it in DisplayDevice and refactors the code in Hwc2::Layer regarding HdrMetadata. When DisplayDevice is created, the ability of accepting metadata will be queried from hardware composer and stored in DisplayDevice. Hwc2::Layer will construct HdrMetadata to PerFrameMetadata when setPerFrameHdrMetadata is called if the incoming meta data is changed. Previously, setLayerPerFrameMetadata was named as setLayerHdrMetadata, but since we move the responsibility of constructing PerFrameMetadata from ComposerHal to Hwc2::Layer, we change the name to setLayerPerFrameMetadata, which is more generic and matches the HIDL interface. BUG: 77831156 Test: Build and flash Change-Id: I447956f4dcf42c90ceb3d29091cd5034ad91061a Merged-In: I447956f4dcf42c90ceb3d29091cd5034ad91061a --- services/surfaceflinger/BufferLayer.cpp | 2 +- services/surfaceflinger/DisplayDevice.cpp | 4 +- services/surfaceflinger/DisplayDevice.h | 14 ++-- .../surfaceflinger/DisplayHardware/ComposerHal.cpp | 54 ++++---------- .../surfaceflinger/DisplayHardware/ComposerHal.h | 12 +++- services/surfaceflinger/DisplayHardware/HWC2.cpp | 82 +++++++++++++++++++++- services/surfaceflinger/DisplayHardware/HWC2.h | 9 ++- .../surfaceflinger/DisplayHardware/HWComposer.cpp | 21 +++++- .../surfaceflinger/DisplayHardware/HWComposer.h | 3 +- services/surfaceflinger/SurfaceFlinger.cpp | 4 +- services/surfaceflinger/tests/hwc2/Android.bp | 1 - .../tests/unittests/DisplayTransactionTest.cpp | 2 +- .../unittests/mock/DisplayHardware/MockComposer.h | 3 +- 13 files changed, 149 insertions(+), 62 deletions(-) (limited to 'services/surfaceflinger/BufferLayer.cpp') diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index 57f474b9ea..7fd9d01a51 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -650,7 +650,7 @@ void BufferLayer::setPerFrameData(const sp& displayDevice) } const HdrMetadata& metadata = mConsumer->getCurrentHdrMetadata(); - error = hwcLayer->setHdrMetadata(metadata); + error = hwcLayer->setPerFrameMetadata(displayDevice->getSupportedPerFrameMetadata(), metadata); if (error != HWC2::Error::None && error != HWC2::Error::Unsupported) { ALOGE("[%s] Failed to set hdrMetadata: %s (%d)", mName.string(), to_string(error).c_str(), static_cast(error)); diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp index cd41662fee..7c6302e70a 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -79,6 +79,7 @@ DisplayDevice::DisplayDevice( int displayHeight, bool hasWideColorGamut, const HdrCapabilities& hdrCapabilities, + const int32_t supportedPerFrameMetadata, int initialPowerMode) : lastCompositionHadVisibleLayers(false), mFlinger(flinger), @@ -103,7 +104,8 @@ DisplayDevice::DisplayDevice( mHasWideColorGamut(hasWideColorGamut), mHasHdr10(false), mHasHLG(false), - mHasDolbyVision(false) + mHasDolbyVision(false), + mSupportedPerFrameMetadata(supportedPerFrameMetadata) { // clang-format on for (Hdr hdrType : hdrCapabilities.getSupportedHdrTypes()) { diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h index cd0bed6631..df5d945405 100644 --- a/services/surfaceflinger/DisplayDevice.h +++ b/services/surfaceflinger/DisplayDevice.h @@ -23,17 +23,16 @@ #include -#include - #include +#include +#include +#include +#include #include #include #include #include -#include -#include -#include #include "RenderArea.h" #include "RenderEngine/Surface.h" @@ -86,6 +85,7 @@ public: int displayHeight, bool hasWideColorGamut, const HdrCapabilities& hdrCapabilities, + const int32_t supportedPerFrameMetadata, int initialPowerMode); // clang-format on @@ -131,6 +131,8 @@ public: int32_t getHwcDisplayId() const { return mHwcDisplayId; } const wp& getDisplayToken() const { return mDisplayToken; } + int32_t getSupportedPerFrameMetadata() const { return mSupportedPerFrameMetadata; } + // We pass in mustRecompose so we can keep VirtualDisplaySurface's state // machine happy without actually queueing a buffer if nothing has changed status_t beginFrame(bool mustRecompose) const; @@ -259,6 +261,8 @@ private: bool mHasHdr10; bool mHasHLG; bool mHasDolbyVision; + + const int32_t mSupportedPerFrameMetadata; }; struct DisplayDeviceState { diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp index c94c290cb2..37ba4339c3 100644 --- a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp +++ b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp @@ -715,48 +715,6 @@ Error Composer::setLayerDataspace(Display display, Layer layer, return Error::NONE; } -Error Composer::setLayerHdrMetadata(Display display, Layer layer, const HdrMetadata& metadata) { - if (!mClient_2_2) { - return Error::UNSUPPORTED; - } - - mWriter.selectDisplay(display); - mWriter.selectLayer(layer); - - std::vector composerMetadata; - using PerFrameMetadataKey = IComposerClient::PerFrameMetadataKey; - if (metadata.validTypes & HdrMetadata::SMPTE2086) { - composerMetadata - .insert(composerMetadata.end(), - {{PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X, - metadata.smpte2086.displayPrimaryRed.x}, - {PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y, - metadata.smpte2086.displayPrimaryRed.y}, - {PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X, - metadata.smpte2086.displayPrimaryGreen.x}, - {PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y, - metadata.smpte2086.displayPrimaryGreen.y}, - {PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X, - metadata.smpte2086.displayPrimaryBlue.x}, - {PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y, - metadata.smpte2086.displayPrimaryBlue.y}, - {PerFrameMetadataKey::WHITE_POINT_X, metadata.smpte2086.whitePoint.x}, - {PerFrameMetadataKey::WHITE_POINT_Y, metadata.smpte2086.whitePoint.y}, - {PerFrameMetadataKey::MAX_LUMINANCE, metadata.smpte2086.maxLuminance}, - {PerFrameMetadataKey::MIN_LUMINANCE, metadata.smpte2086.minLuminance}}); - } - if (metadata.validTypes & HdrMetadata::CTA861_3) { - composerMetadata.insert(composerMetadata.end(), - {{PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL, - metadata.cta8613.maxContentLightLevel}, - {PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL, - metadata.cta8613.maxFrameAverageLightLevel}}); - } - - mWriter.setLayerPerFrameMetadata(composerMetadata); - return Error::NONE; -} - Error Composer::setLayerDisplayFrame(Display display, Layer layer, const IComposerClient::Rect& frame) { @@ -927,6 +885,18 @@ Error Composer::execute() // Composer HAL 2.2 +Error Composer::setLayerPerFrameMetadata(Display display, Layer layer, + const std::vector& perFrameMetadatas) { + if (!mClient_2_2) { + return Error::UNSUPPORTED; + } + + mWriter.selectDisplay(display); + mWriter.selectLayer(layer); + mWriter.setLayerPerFrameMetadata(perFrameMetadatas); + return Error::NONE; +} + Error Composer::getPerFrameMetadataKeys( Display display, std::vector* outKeys) { if (!mClient_2_2) { diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h index e17fd67ef7..beee53966f 100644 --- a/services/surfaceflinger/DisplayHardware/ComposerHal.h +++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h @@ -64,6 +64,9 @@ using V2_2::CommandWriterBase; using V2_2::IComposer; using V2_2::IComposerClient; +using PerFrameMetadata = IComposerClient::PerFrameMetadata; +using PerFrameMetadataKey = IComposerClient::PerFrameMetadataKey; + class Composer { public: virtual ~Composer() = 0; @@ -160,8 +163,6 @@ public: virtual Error setLayerCompositionType(Display display, Layer layer, IComposerClient::Composition type) = 0; virtual Error setLayerDataspace(Display display, Layer layer, Dataspace dataspace) = 0; - virtual Error setLayerHdrMetadata(Display display, Layer layer, - const HdrMetadata& metadata) = 0; virtual Error setLayerDisplayFrame(Display display, Layer layer, const IComposerClient::Rect& frame) = 0; virtual Error setLayerPlaneAlpha(Display display, Layer layer, float alpha) = 0; @@ -176,6 +177,9 @@ public: virtual Error setLayerInfo(Display display, Layer layer, uint32_t type, uint32_t appId) = 0; // Composer HAL 2.2 + virtual Error setLayerPerFrameMetadata( + Display display, Layer layer, + const std::vector& perFrameMetadatas) = 0; virtual Error getPerFrameMetadataKeys( Display display, std::vector* outKeys) = 0; virtual Error getRenderIntents(Display display, ColorMode colorMode, @@ -353,7 +357,6 @@ public: Error setLayerCompositionType(Display display, Layer layer, IComposerClient::Composition type) override; Error setLayerDataspace(Display display, Layer layer, Dataspace dataspace) override; - Error setLayerHdrMetadata(Display display, Layer layer, const HdrMetadata& metadata) override; Error setLayerDisplayFrame(Display display, Layer layer, const IComposerClient::Rect& frame) override; Error setLayerPlaneAlpha(Display display, Layer layer, float alpha) override; @@ -368,6 +371,9 @@ public: Error setLayerInfo(Display display, Layer layer, uint32_t type, uint32_t appId) override; // Composer HAL 2.2 + Error setLayerPerFrameMetadata( + Display display, Layer layer, + const std::vector& perFrameMetadatas) override; Error getPerFrameMetadataKeys( Display display, std::vector* outKeys) override; Error getRenderIntents(Display display, ColorMode colorMode, diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp index 0667f8d5b6..3947318262 100644 --- a/services/surfaceflinger/DisplayHardware/HWC2.cpp +++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp @@ -32,6 +32,7 @@ #include #include +#include using android::Fence; using android::FloatRect; @@ -54,6 +55,11 @@ using android::ui::RenderIntent; namespace { +inline bool hasMetadataKey(const std::set& keys, + const Hwc2::PerFrameMetadataKey& key) { + return keys.find(key) != keys.end(); +} + class ComposerCallbackBridge : public Hwc2::IComposerCallback { public: ComposerCallbackBridge(ComposerCallback* callback, int32_t sequenceId) @@ -370,6 +376,42 @@ Error Display::getColorModes(std::vector* outModes) const return static_cast(intError); } +Error Display::getSupportedPerFrameMetadata(int32_t* outSupportedPerFrameMetadata) const +{ + *outSupportedPerFrameMetadata = 0; + std::vector tmpKeys; + auto intError = mComposer.getPerFrameMetadataKeys(mId, &tmpKeys); + auto error = static_cast(intError); + if (error != Error::None) { + return error; + } + + // Check whether a specific metadata type is supported. A metadata type is considered + // supported if and only if all required fields are supported. + + // SMPTE2086 + std::set keys(tmpKeys.begin(), tmpKeys.end()); + if (hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X) && + hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y) && + hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X) && + hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y) && + hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X) && + hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y) && + hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::WHITE_POINT_X) && + hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::WHITE_POINT_Y) && + hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::MAX_LUMINANCE) && + hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::MIN_LUMINANCE)) { + *outSupportedPerFrameMetadata |= HdrMetadata::Type::SMPTE2086; + } + // CTA861_3 + if (hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL) && + hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL)) { + *outSupportedPerFrameMetadata |= HdrMetadata::Type::CTA861_3; + } + + return Error::None; +} + Error Display::getRenderIntents(ColorMode colorMode, std::vector* outRenderIntents) const { @@ -784,13 +826,49 @@ Error Layer::setDataspace(Dataspace dataspace) return static_cast(intError); } -Error Layer::setHdrMetadata(const android::HdrMetadata& metadata) { +Error Layer::setPerFrameMetadata(const int32_t supportedPerFrameMetadata, + const android::HdrMetadata& metadata) +{ if (metadata == mHdrMetadata) { return Error::None; } mHdrMetadata = metadata; - auto intError = mComposer.setLayerHdrMetadata(mDisplayId, mId, metadata); + int validTypes = mHdrMetadata.validTypes & supportedPerFrameMetadata; + std::vector perFrameMetadatas; + if (validTypes & HdrMetadata::SMPTE2086) { + perFrameMetadatas.insert(perFrameMetadatas.end(), + {{Hwc2::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X, + mHdrMetadata.smpte2086.displayPrimaryRed.x}, + {Hwc2::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y, + mHdrMetadata.smpte2086.displayPrimaryRed.y}, + {Hwc2::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X, + mHdrMetadata.smpte2086.displayPrimaryGreen.x}, + {Hwc2::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y, + mHdrMetadata.smpte2086.displayPrimaryGreen.y}, + {Hwc2::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X, + mHdrMetadata.smpte2086.displayPrimaryBlue.x}, + {Hwc2::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y, + mHdrMetadata.smpte2086.displayPrimaryBlue.y}, + {Hwc2::PerFrameMetadataKey::WHITE_POINT_X, + mHdrMetadata.smpte2086.whitePoint.x}, + {Hwc2::PerFrameMetadataKey::WHITE_POINT_Y, + mHdrMetadata.smpte2086.whitePoint.y}, + {Hwc2::PerFrameMetadataKey::MAX_LUMINANCE, + mHdrMetadata.smpte2086.maxLuminance}, + {Hwc2::PerFrameMetadataKey::MIN_LUMINANCE, + mHdrMetadata.smpte2086.minLuminance}}); + } + + if (validTypes & HdrMetadata::CTA861_3) { + perFrameMetadatas.insert(perFrameMetadatas.end(), + {{Hwc2::PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL, + mHdrMetadata.cta8613.maxContentLightLevel}, + {Hwc2::PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL, + mHdrMetadata.cta8613.maxFrameAverageLightLevel}}); + } + + auto intError = mComposer.setLayerPerFrameMetadata(mDisplayId, mId, perFrameMetadatas); return static_cast(intError); } diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h index aa907eab95..3ac06ec192 100644 --- a/services/surfaceflinger/DisplayHardware/HWC2.h +++ b/services/surfaceflinger/DisplayHardware/HWC2.h @@ -27,7 +27,6 @@ #include #include #include - #include #include #include @@ -212,6 +211,10 @@ public: std::unordered_map* outTypes); [[clang::warn_unused_result]] Error getColorModes( std::vector* outModes) const; + // outSupportedPerFrameMetadata is an opaque bitmask to the callers + // but contains HdrMetadata::Type::*. + [[clang::warn_unused_result]] Error getSupportedPerFrameMetadata( + int32_t* outSupportedPerFrameMetadata) const; [[clang::warn_unused_result]] Error getRenderIntents( android::ui::ColorMode colorMode, std::vector* outRenderIntents) const; @@ -318,7 +321,9 @@ public: [[clang::warn_unused_result]] Error setCompositionType(Composition type); [[clang::warn_unused_result]] Error setDataspace( android::ui::Dataspace dataspace); - [[clang::warn_unused_result]] Error setHdrMetadata(const android::HdrMetadata& metadata); + [[clang::warn_unused_result]] Error setPerFrameMetadata( + const int32_t supportedPerFrameMetadata, + const android::HdrMetadata& metadata); [[clang::warn_unused_result]] Error setDisplayFrame( const android::Rect& frame); [[clang::warn_unused_result]] Error setPlaneAlpha(float alpha); diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp index 0a3ac84db7..1bbf039b75 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -842,6 +842,25 @@ status_t HWComposer::getHdrCapabilities( return NO_ERROR; } +int32_t HWComposer::getSupportedPerFrameMetadata(int32_t displayId) const { + if (!isValidDisplay(displayId)) { + ALOGE("getPerFrameMetadataKeys: Attempted to access invalid display %d", + displayId); + return 0; + } + + int32_t supportedMetadata; + auto error = mDisplayData[displayId].hwcDisplay->getSupportedPerFrameMetadata( + &supportedMetadata); + if (error != HWC2::Error::None) { + ALOGE("getPerFrameMetadataKeys failed for display %d: %s (%d)", displayId, + to_string(error).c_str(), static_cast(error)); + return 0; + } + + return supportedMetadata; +} + std::vector HWComposer::getRenderIntents(int32_t displayId, ui::ColorMode colorMode) const { if (!isValidDisplay(displayId)) { @@ -853,7 +872,7 @@ std::vector HWComposer::getRenderIntents(int32_t displayId, std::vector renderIntents; auto error = mDisplayData[displayId].hwcDisplay->getRenderIntents(colorMode, &renderIntents); if (error != HWC2::Error::None) { - ALOGE("getColorModes failed for display %d: %s (%d)", displayId, + ALOGE("getRenderIntents failed for display %d: %s (%d)", displayId, to_string(error).c_str(), static_cast(error)); return std::vector(); } diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h index 138e1f1113..d7f3b08d48 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.h +++ b/services/surfaceflinger/DisplayHardware/HWComposer.h @@ -24,7 +24,6 @@ #include #include - #include #include #include @@ -137,6 +136,8 @@ public: // Fetches the HDR capabilities of the given display status_t getHdrCapabilities(int32_t displayId, HdrCapabilities* outCapabilities); + int32_t getSupportedPerFrameMetadata(int32_t displayId) const; + // Returns the available RenderIntent of the given display. std::vector getRenderIntents(int32_t displayId, ui::ColorMode colorMode) const; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 58e4fbeb17..e661f03591 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -2314,7 +2314,9 @@ sp SurfaceFlinger::setupNewDisplayDeviceInternal( sp hw = new DisplayDevice(this, state.type, hwcId, state.isSecure, display, nativeWindow, dispSurface, std::move(renderSurface), displayWidth, displayHeight, - hasWideColorGamut, hdrCapabilities, initialPowerMode); + hasWideColorGamut, hdrCapabilities, + getHwComposer().getSupportedPerFrameMetadata(hwcId), + initialPowerMode); if (maxFrameBufferAcquiredBuffers >= 3) { nativeWindowSurface->preallocateBuffers(); diff --git a/services/surfaceflinger/tests/hwc2/Android.bp b/services/surfaceflinger/tests/hwc2/Android.bp index 6c0e4abcfe..0957d6a903 100644 --- a/services/surfaceflinger/tests/hwc2/Android.bp +++ b/services/surfaceflinger/tests/hwc2/Android.bp @@ -41,7 +41,6 @@ cc_test { "libmath", ], shared_libs: [ - "android.hardware.graphics.common@1.0", "android.hardware.graphics.common@1.1", "libcutils", "libEGL", diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp index 7257b46501..f39ca009f6 100644 --- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp +++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp @@ -80,7 +80,7 @@ protected: sp build() { return new DisplayDevice(mFlinger.mFlinger.get(), mType, mHwcId, false, mDisplayToken, mNativeWindow, mDisplaySurface, std::move(mRenderSurface), 0, - 0, false, {}, HWC_POWER_MODE_NORMAL); + 0, false, {}, 0, HWC_POWER_MODE_NORMAL); } FakeDisplayDeviceFactory& setNativeWindow(const sp& nativeWindow) { diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h index 8be277915e..267670aca5 100644 --- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h +++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h @@ -99,7 +99,8 @@ public: MOCK_METHOD3(setLayerColor, Error(Display, Layer, const IComposerClient::Color&)); MOCK_METHOD3(setLayerCompositionType, Error(Display, Layer, IComposerClient::Composition)); MOCK_METHOD3(setLayerDataspace, Error(Display, Layer, Dataspace)); - MOCK_METHOD3(setLayerHdrMetadata, Error(Display, Layer, const HdrMetadata&)); + MOCK_METHOD3(setLayerPerFrameMetadata, + Error(Display, Layer, const std::vector&)); MOCK_METHOD3(setLayerDisplayFrame, Error(Display, Layer, const IComposerClient::Rect&)); MOCK_METHOD3(setLayerPlaneAlpha, Error(Display, Layer, float)); MOCK_METHOD3(setLayerSidebandStream, Error(Display, Layer, const native_handle_t*)); -- cgit v1.2.3-59-g8ed1b From 0102ad2d522de255efabd50adf6c6a27811344f4 Mon Sep 17 00:00:00 2001 From: Yiwei Zhang Date: Wed, 2 May 2018 17:37:17 -0700 Subject: SurfaceFlinger TimeStats Metrics Add timestats metrics for SurfaceFlinger. Keep track of global metrics like total frames, missed frames, frames fellback to client compositions, etc, as well as layer timing metrics like the delta combination of postTime, desiredPresentTime, acqureTime, latchTime, presentTime, etc. This metric is aimed at GMScore. Test: dumpsys SurfaceFlinger --timestats [go/sf-timestats for more args] Bug: b/70388650 Change-Id: I6e4545aef62f7893020533a4e7521541ea453ecd Merged-In: I6e4545aef62f7893020533a4e7521541ea453ecd --- services/surfaceflinger/Android.bp | 4 + services/surfaceflinger/BufferLayer.cpp | 17 +- services/surfaceflinger/Layer.cpp | 6 + services/surfaceflinger/Layer.h | 3 + services/surfaceflinger/SurfaceFlinger.cpp | 28 +- services/surfaceflinger/SurfaceFlinger.h | 2 + services/surfaceflinger/TimeStats/TimeStats.cpp | 498 +++++++++++++++++++++ services/surfaceflinger/TimeStats/TimeStats.h | 103 +++++ .../TimeStats/timestatsproto/Android.bp | 55 +++ .../TimeStats/timestatsproto/TimeStatsHelper.cpp | 156 +++++++ .../include/timestatsproto/TimeStatsHelper.h | 72 +++ .../include/timestatsproto/TimeStatsProtoHeader.h | 23 + .../TimeStats/timestatsproto/jarjar-rules.txt | 1 + .../TimeStats/timestatsproto/timestats.proto | 69 +++ services/surfaceflinger/tests/Android.bp | 1 + services/surfaceflinger/tests/fakehwc/Android.bp | 1 + 16 files changed, 1030 insertions(+), 9 deletions(-) create mode 100644 services/surfaceflinger/TimeStats/TimeStats.cpp create mode 100644 services/surfaceflinger/TimeStats/TimeStats.h create mode 100644 services/surfaceflinger/TimeStats/timestatsproto/Android.bp create mode 100644 services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp create mode 100644 services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h create mode 100644 services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsProtoHeader.h create mode 100644 services/surfaceflinger/TimeStats/timestatsproto/jarjar-rules.txt create mode 100644 services/surfaceflinger/TimeStats/timestatsproto/timestats.proto (limited to 'services/surfaceflinger/BufferLayer.cpp') diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp index 5b1e631b4d..6a69844d9f 100644 --- a/services/surfaceflinger/Android.bp +++ b/services/surfaceflinger/Android.bp @@ -45,6 +45,7 @@ cc_defaults { "libpdx_default_transport", "libprotobuf-cpp-lite", "libsync", + "libtimestats_proto", "libui", "libutils", "libvulkan", @@ -124,6 +125,7 @@ filegroup { "SurfaceFlinger.cpp", "SurfaceInterceptor.cpp", "SurfaceTracing.cpp", + "TimeStats/TimeStats.cpp", "Transform.cpp", ], } @@ -172,6 +174,7 @@ cc_binary { "liblayers_proto", "liblog", "libsurfaceflinger", + "libtimestats_proto", "libutils", ], static_libs: [ @@ -213,5 +216,6 @@ cc_library_shared { subdirs = [ "layerproto", + "TimeStats/timestatsproto", "tests", ] diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index 7fd9d01a51..4c3844e130 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -316,6 +316,9 @@ bool BufferLayer::onPostComposition(const std::shared_ptr& glDoneFenc nsecs_t desiredPresentTime = mConsumer->getTimestamp(); mFrameTracker.setDesiredPresentTime(desiredPresentTime); + const std::string layerName(getName().c_str()); + mTimeStats.setDesiredTime(layerName, mCurrentFrameNumber, desiredPresentTime); + std::shared_ptr frameReadyFence = mConsumer->getCurrentFenceTime(); if (frameReadyFence->isValid()) { mFrameTracker.setFrameReadyFence(std::move(frameReadyFence)); @@ -326,12 +329,15 @@ bool BufferLayer::onPostComposition(const std::shared_ptr& glDoneFenc } if (presentFence->isValid()) { + mTimeStats.setPresentFence(layerName, mCurrentFrameNumber, presentFence); mFrameTracker.setActualPresentFence(std::shared_ptr(presentFence)); } else { // The HWC doesn't support present fences, so use the refresh // timestamp instead. - mFrameTracker.setActualPresentTime( - mFlinger->getHwComposer().getRefreshTimestamp(HWC_DISPLAY_PRIMARY)); + const nsecs_t actualPresentTime = + mFlinger->getHwComposer().getRefreshTimestamp(HWC_DISPLAY_PRIMARY); + mTimeStats.setPresentTime(layerName, mCurrentFrameNumber, actualPresentTime); + mFrameTracker.setActualPresentTime(actualPresentTime); } mFrameTracker.advanceFrame(); @@ -441,6 +447,7 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime // and return early if (queuedBuffer) { Mutex::Autolock lock(mQueueItemLock); + mTimeStats.removeTimeRecord(getName().c_str(), mQueueItems[0].mFrameNumber); mQueueItems.removeAt(0); android_atomic_dec(&mQueuedFrames); } @@ -454,6 +461,7 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime Mutex::Autolock lock(mQueueItemLock); mQueueItems.clear(); android_atomic_and(0, &mQueuedFrames); + mTimeStats.clearLayerRecord(getName().c_str()); } // Once we have hit this state, the shadow queue may no longer @@ -474,10 +482,15 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime // Remove any stale buffers that have been dropped during // updateTexImage while (mQueueItems[0].mFrameNumber != currentFrameNumber) { + mTimeStats.removeTimeRecord(getName().c_str(), mQueueItems[0].mFrameNumber); mQueueItems.removeAt(0); android_atomic_dec(&mQueuedFrames); } + const std::string layerName(getName().c_str()); + mTimeStats.setAcquireFence(layerName, currentFrameNumber, mQueueItems[0].mFenceTime); + mTimeStats.setLatchTime(layerName, currentFrameNumber, latchTime); + mQueueItems.removeAt(0); } diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index bbc974de2f..2802fc7b21 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -1532,10 +1532,16 @@ void Layer::dumpFrameEvents(String8& result) { void Layer::onDisconnect() { Mutex::Autolock lock(mFrameEventHistoryMutex); mFrameEventHistory.onDisconnect(); + mTimeStats.onDisconnect(getName().c_str()); } void Layer::addAndGetFrameTimestamps(const NewFrameEventsEntry* newTimestamps, FrameEventHistoryDelta* outDelta) { + if (newTimestamps) { + mTimeStats.setPostTime(getName().c_str(), newTimestamps->frameNumber, + newTimestamps->postedTime); + } + Mutex::Autolock lock(mFrameEventHistoryMutex); if (newTimestamps) { // If there are any unsignaled fences in the aquire timeline at this diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index be3967b2cb..0b15b67062 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -41,6 +41,7 @@ #include "LayerVector.h" #include "MonitoredProducer.h" #include "SurfaceFlinger.h" +#include "TimeStats/TimeStats.h" #include "Transform.h" #include @@ -737,6 +738,8 @@ protected: FenceTimeline mAcquireTimeline; FenceTimeline mReleaseTimeline; + TimeStats& mTimeStats = TimeStats::getInstance(); + // main thread int mActiveBufferSlot; sp mActiveBuffer; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index f736c8cfda..e3a47069f8 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -1470,9 +1470,13 @@ void SurfaceFlinger::onMessageReceived(int32_t what) { Fence::SIGNAL_TIME_PENDING); ATRACE_INT("FrameMissed", static_cast(frameMissed)); if (mPropagateBackpressure && frameMissed) { + mTimeStats.incrementMissedFrames(true); signalLayerUpdate(); break; } + if (frameMissed) { + mTimeStats.incrementMissedFrames(false); + } // Now that we're going to make it to the handleMessageTransaction() // call below it's safe to call updateVrFlinger(), which will @@ -1771,6 +1775,11 @@ void SurfaceFlinger::postComposition(nsecs_t refreshStartTime) mAnimFrameTracker.advanceFrame(); } + mTimeStats.incrementTotalFrames(); + if (mHadClientComposition) { + mTimeStats.incrementClientCompositionFrames(); + } + if (getBE().mHwc->isConnected(HWC_DISPLAY_PRIMARY) && hw->getPowerMode() == HWC_POWER_MODE_OFF) { return; @@ -3824,12 +3833,6 @@ status_t SurfaceFlinger::doDump(int fd, const Vector& args, bool asPro size_t index = 0; size_t numArgs = args.size(); - if (asProto) { - LayersProto layersProto = dumpProtoInfo(LayerVector::StateSet::Current); - result.append(layersProto.SerializeAsString().c_str(), layersProto.ByteSize()); - dumpAll = false; - } - if (numArgs) { if ((index < numArgs) && (args[index] == String16("--list"))) { @@ -3906,10 +3909,21 @@ status_t SurfaceFlinger::doDump(int fd, const Vector& args, bool asPro mLayerStats.dump(result); dumpAll = false; } + + if ((index < numArgs) && (args[index] == String16("--timestats"))) { + index++; + mTimeStats.parseArgs(asProto, args, index, result); + dumpAll = false; + } } if (dumpAll) { - dumpAllLocked(args, index, result); + if (asProto) { + LayersProto layersProto = dumpProtoInfo(LayerVector::StateSet::Current); + result.append(layersProto.SerializeAsString().c_str(), layersProto.ByteSize()); + } else { + dumpAllLocked(args, index, result); + } } if (locked) { diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 33706dafe9..a1c8a33674 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -63,6 +63,7 @@ #include "SurfaceInterceptor.h" #include "SurfaceTracing.h" #include "StartPropertySetThread.h" +#include "TimeStats/TimeStats.h" #include "VSyncModulator.h" #include "DisplayHardware/HWC2.h" @@ -815,6 +816,7 @@ private: std::make_unique(this); SurfaceTracing mTracing; LayerStats mLayerStats; + TimeStats& mTimeStats = TimeStats::getInstance(); bool mUseHwcVirtualDisplays = false; // Restrict layers to use two buffers in their bufferqueues. diff --git a/services/surfaceflinger/TimeStats/TimeStats.cpp b/services/surfaceflinger/TimeStats/TimeStats.cpp new file mode 100644 index 0000000000..5f2dd32182 --- /dev/null +++ b/services/surfaceflinger/TimeStats/TimeStats.cpp @@ -0,0 +1,498 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#undef LOG_TAG +#define LOG_TAG "TimeStats" +#define ATRACE_TAG ATRACE_TAG_GRAPHICS + +#include "TimeStats.h" + +#include + +#include + +#include +#include + +#include +#include + +namespace android { + +TimeStats& TimeStats::getInstance() { + static std::unique_ptr sInstance; + static std::once_flag sOnceFlag; + + std::call_once(sOnceFlag, [] { sInstance.reset(new TimeStats); }); + return *sInstance.get(); +} + +void TimeStats::parseArgs(bool asProto, const Vector& args, size_t& index, + String8& result) { + ATRACE_CALL(); + + if (args.size() > index + 10) { + ALOGD("Invalid args count"); + return; + } + + std::unordered_map argsMap; + while (index < args.size()) { + argsMap[std::string(String8(args[index]).c_str())] = index; + ++index; + } + + if (argsMap.count("-disable")) { + disable(); + } + + if (argsMap.count("-dump")) { + int64_t maxLayers = 0; + auto iter = argsMap.find("-maxlayers"); + if (iter != argsMap.end() && iter->second + 1 < static_cast(args.size())) { + maxLayers = strtol(String8(args[iter->second + 1]).c_str(), nullptr, 10); + maxLayers = std::clamp(maxLayers, int64_t(0), int64_t(UINT32_MAX)); + } + + dump(asProto, static_cast(maxLayers), result); + } + + if (argsMap.count("-clear")) { + clear(); + } + + if (argsMap.count("-enable")) { + enable(); + } +} + +void TimeStats::incrementTotalFrames() { + if (!mEnabled.load()) return; + + ATRACE_CALL(); + + std::lock_guard lock(mMutex); + timeStats.totalFrames++; +} + +void TimeStats::incrementMissedFrames(bool propagateBackpressure) { + if (!mEnabled.load()) return; + + ATRACE_CALL(); + + std::lock_guard lock(mMutex); + if (propagateBackpressure) { + timeStats.totalFrames--; + } + timeStats.missedFrames++; +} + +void TimeStats::incrementClientCompositionFrames() { + if (!mEnabled.load()) return; + + ATRACE_CALL(); + + std::lock_guard lock(mMutex); + timeStats.clientCompositionFrames++; +} + +bool TimeStats::recordReadyLocked(const std::string& layerName, TimeRecord* timeRecord) { + if (!timeRecord->ready) { + ALOGV("[%s]-[%" PRIu64 "]-presentFence is still not received", layerName.c_str(), + timeRecord->frameNumber); + return false; + } + + if (timeRecord->acquireFence != nullptr) { + if (timeRecord->acquireFence->getSignalTime() == Fence::SIGNAL_TIME_PENDING) { + return false; + } + if (timeRecord->acquireFence->getSignalTime() != Fence::SIGNAL_TIME_INVALID) { + timeRecord->acquireTime = timeRecord->acquireFence->getSignalTime(); + timeRecord->acquireFence = nullptr; + } else { + ALOGV("[%s]-[%" PRIu64 "]-acquireFence signal time is invalid", layerName.c_str(), + timeRecord->frameNumber); + } + } + + if (timeRecord->presentFence != nullptr) { + if (timeRecord->presentFence->getSignalTime() == Fence::SIGNAL_TIME_PENDING) { + return false; + } + if (timeRecord->presentFence->getSignalTime() != Fence::SIGNAL_TIME_INVALID) { + timeRecord->presentTime = timeRecord->presentFence->getSignalTime(); + timeRecord->presentFence = nullptr; + } else { + ALOGV("[%s]-[%" PRIu64 "]-presentFence signal time invalid", layerName.c_str(), + timeRecord->frameNumber); + } + } + + return true; +} + +static int32_t msBetween(nsecs_t start, nsecs_t end) { + int64_t delta = (end - start) / 1000000; + delta = std::clamp(delta, int64_t(INT32_MIN), int64_t(INT32_MAX)); + return static_cast(delta); +} + +void TimeStats::flushAvailableRecordsToStatsLocked(const std::string& layerName) { + ATRACE_CALL(); + + LayerRecord& layerRecord = timeStatsTracker[layerName]; + TimeRecord& prevTimeRecord = layerRecord.prevTimeRecord; + std::vector& timeRecords = layerRecord.timeRecords; + while (!timeRecords.empty()) { + if (!recordReadyLocked(layerName, &timeRecords[0])) break; + ALOGV("[%s]-[%" PRIu64 "]-presentFenceTime[%" PRId64 "]", layerName.c_str(), + timeRecords[0].frameNumber, timeRecords[0].presentTime); + + if (prevTimeRecord.ready) { + if (!timeStats.stats.count(layerName)) { + timeStats.stats[layerName].layerName = layerName; + timeStats.stats[layerName].statsStart = static_cast(std::time(0)); + } + TimeStatsHelper::TimeStatsLayer& timeStatsLayer = timeStats.stats[layerName]; + timeStatsLayer.totalFrames++; + + const int32_t postToPresentMs = + msBetween(timeRecords[0].postTime, timeRecords[0].presentTime); + ALOGV("[%s]-[%" PRIu64 "]-post2present[%d]", layerName.c_str(), + timeRecords[0].frameNumber, postToPresentMs); + timeStatsLayer.deltas["post2present"].insert(postToPresentMs); + + const int32_t acquireToPresentMs = + msBetween(timeRecords[0].acquireTime, timeRecords[0].presentTime); + ALOGV("[%s]-[%" PRIu64 "]-acquire2present[%d]", layerName.c_str(), + timeRecords[0].frameNumber, acquireToPresentMs); + timeStatsLayer.deltas["acquire2present"].insert(acquireToPresentMs); + + const int32_t latchToPresentMs = + msBetween(timeRecords[0].latchTime, timeRecords[0].presentTime); + ALOGV("[%s]-[%" PRIu64 "]-latch2present[%d]", layerName.c_str(), + timeRecords[0].frameNumber, latchToPresentMs); + timeStatsLayer.deltas["latch2present"].insert(latchToPresentMs); + + const int32_t desiredToPresentMs = + msBetween(timeRecords[0].desiredTime, timeRecords[0].presentTime); + ALOGV("[%s]-[%" PRIu64 "]-desired2present[%d]", layerName.c_str(), + timeRecords[0].frameNumber, desiredToPresentMs); + timeStatsLayer.deltas["desired2present"].insert(desiredToPresentMs); + + const int32_t presentToPresentMs = + msBetween(prevTimeRecord.presentTime, timeRecords[0].presentTime); + ALOGV("[%s]-[%" PRIu64 "]-present2present[%d]", layerName.c_str(), + timeRecords[0].frameNumber, presentToPresentMs); + timeStatsLayer.deltas["present2present"].insert(presentToPresentMs); + + timeStats.stats[layerName].statsEnd = static_cast(std::time(0)); + } + prevTimeRecord = timeRecords[0]; + // TODO(zzyiwei): change timeRecords to use std::deque + timeRecords.erase(timeRecords.begin()); + layerRecord.waitData--; + } +} + +static bool layerNameIsValid(const std::string& layerName) { + // This regular expression captures the following layer names for instance: + // 1) StatusBat#0 + // 2) NavigationBar#1 + // 3) com.*#0 + // 4) SurfaceView - com.*#0 + // Using [-\\s\t]+ for the conjunction part between SurfaceView and com.* is + // a bit more robust in case there's a slight change. + // The layer name would only consist of . / $ _ 0-9 a-z A-Z in most cases. + std::regex re("(((SurfaceView[-\\s\\t]+)?com\\.[./$\\w]+)|((Status|Navigation)Bar))#\\d+"); + return std::regex_match(layerName.begin(), layerName.end(), re); +} + +void TimeStats::setPostTime(const std::string& layerName, uint64_t frameNumber, nsecs_t postTime) { + if (!mEnabled.load()) return; + + ATRACE_CALL(); + ALOGV("[%s]-[%" PRIu64 "]-PostTime[%" PRId64 "]", layerName.c_str(), frameNumber, postTime); + + std::lock_guard lock(mMutex); + if (!timeStatsTracker.count(layerName) && !layerNameIsValid(layerName)) { + return; + } + LayerRecord& layerRecord = timeStatsTracker[layerName]; + if (layerRecord.timeRecords.size() == MAX_NUM_TIME_RECORDS) { + ALOGV("[%s]-timeRecords is already at its maximum size[%zu]", layerName.c_str(), + MAX_NUM_TIME_RECORDS); + // TODO(zzyiwei): if this happens, there must be a present fence missing + // or waitData is not in the correct position. Need to think out a + // reasonable way to recover from this state. + return; + } + // For most media content, the acquireFence is invalid because the buffer is + // ready at the queueBuffer stage. In this case, acquireTime should be given + // a default value as postTime. + TimeRecord timeRecord = { + .frameNumber = frameNumber, + .postTime = postTime, + .acquireTime = postTime, + }; + layerRecord.timeRecords.push_back(timeRecord); + if (layerRecord.waitData < 0 || + layerRecord.waitData >= static_cast(layerRecord.timeRecords.size())) + layerRecord.waitData = layerRecord.timeRecords.size() - 1; +} + +void TimeStats::setLatchTime(const std::string& layerName, uint64_t frameNumber, + nsecs_t latchTime) { + if (!mEnabled.load()) return; + + ATRACE_CALL(); + ALOGV("[%s]-[%" PRIu64 "]-LatchTime[%" PRId64 "]", layerName.c_str(), frameNumber, latchTime); + + std::lock_guard lock(mMutex); + if (!timeStatsTracker.count(layerName)) return; + LayerRecord& layerRecord = timeStatsTracker[layerName]; + TimeRecord& timeRecord = layerRecord.timeRecords[layerRecord.waitData]; + if (timeRecord.frameNumber == frameNumber) { + timeRecord.latchTime = latchTime; + } +} + +void TimeStats::setDesiredTime(const std::string& layerName, uint64_t frameNumber, + nsecs_t desiredTime) { + if (!mEnabled.load()) return; + + ATRACE_CALL(); + ALOGV("[%s]-[%" PRIu64 "]-DesiredTime[%" PRId64 "]", layerName.c_str(), frameNumber, + desiredTime); + + std::lock_guard lock(mMutex); + if (!timeStatsTracker.count(layerName)) return; + LayerRecord& layerRecord = timeStatsTracker[layerName]; + TimeRecord& timeRecord = layerRecord.timeRecords[layerRecord.waitData]; + if (timeRecord.frameNumber == frameNumber) { + timeRecord.desiredTime = desiredTime; + } +} + +void TimeStats::setAcquireTime(const std::string& layerName, uint64_t frameNumber, + nsecs_t acquireTime) { + if (!mEnabled.load()) return; + + ATRACE_CALL(); + ALOGV("[%s]-[%" PRIu64 "]-AcquireTime[%" PRId64 "]", layerName.c_str(), frameNumber, + acquireTime); + + std::lock_guard lock(mMutex); + if (!timeStatsTracker.count(layerName)) return; + LayerRecord& layerRecord = timeStatsTracker[layerName]; + TimeRecord& timeRecord = layerRecord.timeRecords[layerRecord.waitData]; + if (timeRecord.frameNumber == frameNumber) { + timeRecord.acquireTime = acquireTime; + } +} + +void TimeStats::setAcquireFence(const std::string& layerName, uint64_t frameNumber, + const std::shared_ptr& acquireFence) { + if (!mEnabled.load()) return; + + ATRACE_CALL(); + ALOGV("[%s]-[%" PRIu64 "]-AcquireFenceTime[%" PRId64 "]", layerName.c_str(), frameNumber, + acquireFence->getSignalTime()); + + std::lock_guard lock(mMutex); + if (!timeStatsTracker.count(layerName)) return; + LayerRecord& layerRecord = timeStatsTracker[layerName]; + TimeRecord& timeRecord = layerRecord.timeRecords[layerRecord.waitData]; + if (timeRecord.frameNumber == frameNumber) { + timeRecord.acquireFence = acquireFence; + } +} + +void TimeStats::setPresentTime(const std::string& layerName, uint64_t frameNumber, + nsecs_t presentTime) { + if (!mEnabled.load()) return; + + ATRACE_CALL(); + ALOGV("[%s]-[%" PRIu64 "]-PresentTime[%" PRId64 "]", layerName.c_str(), frameNumber, + presentTime); + + std::lock_guard lock(mMutex); + if (!timeStatsTracker.count(layerName)) return; + LayerRecord& layerRecord = timeStatsTracker[layerName]; + TimeRecord& timeRecord = layerRecord.timeRecords[layerRecord.waitData]; + if (timeRecord.frameNumber == frameNumber) { + timeRecord.presentTime = presentTime; + timeRecord.ready = true; + layerRecord.waitData++; + } + + flushAvailableRecordsToStatsLocked(layerName); +} + +void TimeStats::setPresentFence(const std::string& layerName, uint64_t frameNumber, + const std::shared_ptr& presentFence) { + if (!mEnabled.load()) return; + + ATRACE_CALL(); + ALOGV("[%s]-[%" PRIu64 "]-PresentFenceTime[%" PRId64 "]", layerName.c_str(), frameNumber, + presentFence->getSignalTime()); + + std::lock_guard lock(mMutex); + if (!timeStatsTracker.count(layerName)) return; + LayerRecord& layerRecord = timeStatsTracker[layerName]; + TimeRecord& timeRecord = layerRecord.timeRecords[layerRecord.waitData]; + if (timeRecord.frameNumber == frameNumber) { + timeRecord.presentFence = presentFence; + timeRecord.ready = true; + layerRecord.waitData++; + } + + flushAvailableRecordsToStatsLocked(layerName); +} + +void TimeStats::onDisconnect(const std::string& layerName) { + if (!mEnabled.load()) return; + + ATRACE_CALL(); + ALOGV("[%s]-onDisconnect", layerName.c_str()); + + std::lock_guard lock(mMutex); + if (!timeStatsTracker.count(layerName)) return; + flushAvailableRecordsToStatsLocked(layerName); + timeStatsTracker.erase(layerName); +} + +void TimeStats::clearLayerRecord(const std::string& layerName) { + if (!mEnabled.load()) return; + + ATRACE_CALL(); + ALOGV("[%s]-clearLayerRecord", layerName.c_str()); + + std::lock_guard lock(mMutex); + if (!timeStatsTracker.count(layerName)) return; + LayerRecord& layerRecord = timeStatsTracker[layerName]; + layerRecord.timeRecords.clear(); + layerRecord.prevTimeRecord.ready = false; + layerRecord.waitData = -1; +} + +void TimeStats::removeTimeRecord(const std::string& layerName, uint64_t frameNumber) { + if (!mEnabled.load()) return; + + ATRACE_CALL(); + ALOGV("[%s]-[%" PRIu64 "]-removeTimeRecord", layerName.c_str(), frameNumber); + + std::lock_guard lock(mMutex); + if (!timeStatsTracker.count(layerName)) return; + LayerRecord& layerRecord = timeStatsTracker[layerName]; + size_t removeAt = 0; + for (const TimeRecord& record : layerRecord.timeRecords) { + if (record.frameNumber == frameNumber) break; + removeAt++; + } + if (removeAt == layerRecord.timeRecords.size()) return; + layerRecord.timeRecords.erase(layerRecord.timeRecords.begin() + removeAt); + if (layerRecord.waitData > static_cast(removeAt)) { + --layerRecord.waitData; + } +} + +void TimeStats::enable() { + if (mEnabled.load()) return; + + ATRACE_CALL(); + + std::lock_guard lock(mMutex); + ALOGD("Enabled"); + mEnabled.store(true); + timeStats.statsStart = static_cast(std::time(0)); +} + +void TimeStats::disable() { + if (!mEnabled.load()) return; + + ATRACE_CALL(); + + std::lock_guard lock(mMutex); + ALOGD("Disabled"); + mEnabled.store(false); + timeStats.statsEnd = static_cast(std::time(0)); +} + +void TimeStats::clear() { + ATRACE_CALL(); + + std::lock_guard lock(mMutex); + ALOGD("Cleared"); + timeStats.dumpStats.clear(); + timeStats.stats.clear(); + timeStats.statsStart = (mEnabled.load() ? static_cast(std::time(0)) : 0); + timeStats.statsEnd = 0; + timeStats.totalFrames = 0; + timeStats.missedFrames = 0; + timeStats.clientCompositionFrames = 0; +} + +bool TimeStats::isEnabled() { + return mEnabled.load(); +} + +void TimeStats::dump(bool asProto, uint32_t maxLayers, String8& result) { + ATRACE_CALL(); + + std::lock_guard lock(mMutex); + if (timeStats.statsStart == 0) { + return; + } + + timeStats.statsEnd = static_cast(std::time(0)); + + // TODO(zzyiwei): refactor dumpStats into TimeStatsHelper + timeStats.dumpStats.clear(); + for (auto& ele : timeStats.stats) { + timeStats.dumpStats.push_back(&ele.second); + } + + std::sort(timeStats.dumpStats.begin(), timeStats.dumpStats.end(), + [](TimeStatsHelper::TimeStatsLayer* const& l, + TimeStatsHelper::TimeStatsLayer* const& r) { + return l->totalFrames > r->totalFrames; + }); + + if (maxLayers != 0 && maxLayers < timeStats.dumpStats.size()) { + timeStats.dumpStats.resize(maxLayers); + } + + if (asProto) { + dumpAsProtoLocked(result); + } else { + dumpAsTextLocked(result); + } +} + +void TimeStats::dumpAsTextLocked(String8& result) { + ALOGD("Dumping TimeStats as text"); + result.append(timeStats.toString().c_str()); + result.append("\n"); +} + +void TimeStats::dumpAsProtoLocked(String8& result) { + ALOGD("Dumping TimeStats as proto"); + SFTimeStatsGlobalProto timeStatsProto = timeStats.toProto(); + result.append(timeStatsProto.SerializeAsString().c_str(), timeStatsProto.ByteSize()); +} + +} // namespace android diff --git a/services/surfaceflinger/TimeStats/TimeStats.h b/services/surfaceflinger/TimeStats/TimeStats.h new file mode 100644 index 0000000000..2410265a0d --- /dev/null +++ b/services/surfaceflinger/TimeStats/TimeStats.h @@ -0,0 +1,103 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include + +using namespace android::surfaceflinger; + +namespace android { +class String8; + +class TimeStats { + // TODO(zzyiwei): Bound the timeStatsTracker with weighted LRU + // static const size_t MAX_NUM_LAYER_RECORDS = 200; + static const size_t MAX_NUM_TIME_RECORDS = 64; + + struct TimeRecord { + bool ready = false; + uint64_t frameNumber = 0; + nsecs_t postTime = 0; + nsecs_t latchTime = 0; + nsecs_t acquireTime = 0; + nsecs_t desiredTime = 0; + nsecs_t presentTime = 0; + std::shared_ptr acquireFence; + std::shared_ptr presentFence; + }; + + struct LayerRecord { + // This is the index in timeRecords, at which the timestamps for that + // specific frame are still not fully received. This is not waiting for + // fences to signal, but rather waiting to receive those fences/timestamps. + int32_t waitData = -1; + TimeRecord prevTimeRecord; + std::vector timeRecords; + }; + +public: + static TimeStats& getInstance(); + void parseArgs(bool asProto, const Vector& args, size_t& index, String8& result); + void incrementTotalFrames(); + void incrementMissedFrames(bool propagateBackpressure); + void incrementClientCompositionFrames(); + + void setPostTime(const std::string& layerName, uint64_t frameNumber, nsecs_t postTime); + void setLatchTime(const std::string& layerName, uint64_t frameNumber, nsecs_t latchTime); + void setDesiredTime(const std::string& layerName, uint64_t frameNumber, nsecs_t desiredTime); + void setAcquireTime(const std::string& layerName, uint64_t frameNumber, nsecs_t acquireTime); + void setAcquireFence(const std::string& layerName, uint64_t frameNumber, + const std::shared_ptr& acquireFence); + void setPresentTime(const std::string& layerName, uint64_t frameNumber, nsecs_t presentTime); + void setPresentFence(const std::string& layerName, uint64_t frameNumber, + const std::shared_ptr& presentFence); + void onDisconnect(const std::string& layerName); + void clearLayerRecord(const std::string& layerName); + void removeTimeRecord(const std::string& layerName, uint64_t frameNumber); + +private: + TimeStats() = default; + + bool recordReadyLocked(const std::string& layerName, TimeRecord* timeRecord); + void flushAvailableRecordsToStatsLocked(const std::string& layerName); + + void enable(); + void disable(); + void clear(); + bool isEnabled(); + void dump(bool asProto, uint32_t maxLayer, String8& result); + void dumpAsTextLocked(String8& result); + void dumpAsProtoLocked(String8& result); + + std::atomic mEnabled = false; + std::mutex mMutex; + TimeStatsHelper::TimeStatsGlobal timeStats; + std::unordered_map timeStatsTracker; +}; + +} // namespace android diff --git a/services/surfaceflinger/TimeStats/timestatsproto/Android.bp b/services/surfaceflinger/TimeStats/timestatsproto/Android.bp new file mode 100644 index 0000000000..66aa719381 --- /dev/null +++ b/services/surfaceflinger/TimeStats/timestatsproto/Android.bp @@ -0,0 +1,55 @@ +cc_library_shared { + name: "libtimestats_proto", + vendor_available: true, + export_include_dirs: ["include"], + + srcs: [ + "TimeStatsHelper.cpp", + "timestats.proto", + ], + + shared_libs: [ + "android.hardware.graphics.common@1.1", + "libui", + "libprotobuf-cpp-lite", + "libbase", + "liblog", + ], + + proto: { + export_proto_headers: true, + }, + + cppflags: [ + "-Werror", + "-Wno-unused-parameter", + "-Wno-format", + "-Wno-c++98-compat-pedantic", + "-Wno-float-conversion", + "-Wno-disabled-macro-expansion", + "-Wno-float-equal", + "-Wno-sign-conversion", + "-Wno-padded", + "-Wno-old-style-cast", + "-Wno-undef", + ], + +} + +java_library_static { + name: "timestatsprotosnano", + host_supported: true, + proto: { + type: "nano", + }, + srcs: ["*.proto"], + no_framework_libs: true, + target: { + android: { + jarjar_rules: "jarjar-rules.txt", + }, + host: { + static_libs: ["libprotobuf-java-nano"], + }, + }, +} diff --git a/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp b/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp new file mode 100644 index 0000000000..ec0570d619 --- /dev/null +++ b/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include + +#include +#include + +#define HISTOGRAM_SIZE 85 + +using android::base::StringAppendF; +using android::base::StringPrintf; + +namespace android { +namespace surfaceflinger { + +// Time buckets for histogram, the calculated time deltas will be lower bounded +// to the buckets in this array. +static const std::array histogramConfig = + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 36, 38, 40, 42, 44, 46, 48, 50, 54, 58, 62, 66, 70, 74, 78, 82, + 86, 90, 94, 98, 102, 106, 110, 114, 118, 122, 126, 130, 134, 138, 142, 146, 150, + 200, 250, 300, 350, 400, 450, 500, 550, 600, 650, 700, 750, 800, 850, 900, 950, 1000}; + +void TimeStatsHelper::Histogram::insert(int32_t delta) { + if (delta < 0) return; + // std::lower_bound won't work on out of range values + if (delta > histogramConfig[HISTOGRAM_SIZE - 1]) { + hist[histogramConfig[HISTOGRAM_SIZE - 1]]++; + return; + } + auto iter = std::lower_bound(histogramConfig.begin(), histogramConfig.end(), delta); + hist[*iter]++; +} + +float TimeStatsHelper::Histogram::averageTime() { + int64_t ret = 0; + int64_t count = 0; + for (auto ele : hist) { + count += ele.second; + ret += ele.first * ele.second; + } + return static_cast(ret) / count; +} + +std::string TimeStatsHelper::Histogram::toString() { + std::string result; + for (int32_t i = 0; i < HISTOGRAM_SIZE; ++i) { + int32_t bucket = histogramConfig[i]; + int32_t count = (hist.count(bucket) == 0) ? 0 : hist[bucket]; + StringAppendF(&result, "%dms=%d ", bucket, count); + } + result.back() = '\n'; + return result; +} + +static std::string getPackageName(const std::string& layerName) { + // This regular expression captures the following for instance: + // StatusBar in StatusBar#0 + // com.appname in com.appname/com.appname.activity#0 + // com.appname in SurfaceView - com.appname/com.appname.activity#0 + const std::regex re("(?:SurfaceView[-\\s\\t]+)?([^/]+).*#\\d+"); + std::smatch match; + if (std::regex_match(layerName.begin(), layerName.end(), match, re)) { + // There must be a match for group 1 otherwise the whole string is not + // matched and the above will return false + return match[1]; + } + return ""; +} + +std::string TimeStatsHelper::TimeStatsLayer::toString() { + std::string result = ""; + StringAppendF(&result, "layerName = %s\n", layerName.c_str()); + packageName = getPackageName(layerName); + StringAppendF(&result, "packageName = %s\n", packageName.c_str()); + StringAppendF(&result, "statsStart = %lld\n", static_cast(statsStart)); + StringAppendF(&result, "statsEnd = %lld\n", static_cast(statsEnd)); + StringAppendF(&result, "totalFrames= %d\n", totalFrames); + if (deltas.find("present2present") != deltas.end()) { + StringAppendF(&result, "averageFPS = %.3f\n", + 1000.0 / deltas["present2present"].averageTime()); + } + for (auto ele : deltas) { + StringAppendF(&result, "%s histogram is as below:\n", ele.first.c_str()); + StringAppendF(&result, "%s", ele.second.toString().c_str()); + } + + return result; +} + +std::string TimeStatsHelper::TimeStatsGlobal::toString() { + std::string result = "SurfaceFlinger TimeStats:\n"; + StringAppendF(&result, "statsStart = %lld\n", static_cast(statsStart)); + StringAppendF(&result, "statsEnd = %lld\n", static_cast(statsEnd)); + StringAppendF(&result, "totalFrames= %d\n", totalFrames); + StringAppendF(&result, "missedFrames= %d\n", missedFrames); + StringAppendF(&result, "clientCompositionFrames= %d\n", clientCompositionFrames); + StringAppendF(&result, "TimeStats for each layer is as below:\n"); + for (auto ele : dumpStats) { + StringAppendF(&result, "%s", ele->toString().c_str()); + } + + return result; +} + +SFTimeStatsLayerProto TimeStatsHelper::TimeStatsLayer::toProto() { + SFTimeStatsLayerProto layerProto; + layerProto.set_layer_name(layerName); + packageName = getPackageName(layerName); + layerProto.set_package_name(packageName); + layerProto.set_stats_start(statsStart); + layerProto.set_stats_end(statsEnd); + layerProto.set_total_frames(totalFrames); + for (auto ele : deltas) { + SFTimeStatsDeltaProto* deltaProto = layerProto.add_deltas(); + deltaProto->set_delta_name(ele.first); + SFTimeStatsHistogramBucketProto* histProto = deltaProto->add_histograms(); + for (auto histEle : ele.second.hist) { + histProto->set_render_millis(histEle.first); + histProto->set_frame_count(histEle.second); + } + } + return layerProto; +} + +SFTimeStatsGlobalProto TimeStatsHelper::TimeStatsGlobal::toProto() { + SFTimeStatsGlobalProto globalProto; + globalProto.set_stats_start(statsStart); + globalProto.set_stats_end(statsEnd); + globalProto.set_total_frames(totalFrames); + globalProto.set_missed_frames(missedFrames); + globalProto.set_client_composition_frames(clientCompositionFrames); + for (auto ele : dumpStats) { + SFTimeStatsLayerProto* layerProto = globalProto.add_stats(); + layerProto->CopyFrom(ele->toProto()); + } + return globalProto; +} + +} // namespace surfaceflinger +} // namespace android diff --git a/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h b/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h new file mode 100644 index 0000000000..c876f21404 --- /dev/null +++ b/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include + +#include + +#include +#include +#include +#include + +namespace android { +namespace surfaceflinger { + +class TimeStatsHelper { +public: + class Histogram { + public: + // Key is the delta time between timestamps + // Value is the number of appearances of that delta + std::unordered_map hist; + + void insert(int32_t delta); + float averageTime(); + std::string toString(); + }; + + class TimeStatsLayer { + public: + std::string layerName; + std::string packageName; + int64_t statsStart = 0; + int64_t statsEnd = 0; + int32_t totalFrames = 0; + std::unordered_map deltas; + + std::string toString(); + SFTimeStatsLayerProto toProto(); + }; + + class TimeStatsGlobal { + public: + int64_t statsStart = 0; + int64_t statsEnd = 0; + int32_t totalFrames = 0; + int32_t missedFrames = 0; + int32_t clientCompositionFrames = 0; + std::unordered_map stats; + std::vector dumpStats; + + std::string toString(); + SFTimeStatsGlobalProto toProto(); + }; +}; + +} // namespace surfaceflinger +} // namespace android diff --git a/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsProtoHeader.h b/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsProtoHeader.h new file mode 100644 index 0000000000..fe0d150c3b --- /dev/null +++ b/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsProtoHeader.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2018 The Android Open Source Projectlayerproto/LayerProtoHeader.h + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// pragma is used here to disable the warnings emitted from the protobuf +// headers. By adding #pragma before including layer.pb.h, it supresses +// protobuf warnings, but allows the rest of the files to continuing using +// the current flags. +// This file should be included instead of directly including layer.b.h +#pragma GCC system_header +#include diff --git a/services/surfaceflinger/TimeStats/timestatsproto/jarjar-rules.txt b/services/surfaceflinger/TimeStats/timestatsproto/jarjar-rules.txt new file mode 100644 index 0000000000..40043a861c --- /dev/null +++ b/services/surfaceflinger/TimeStats/timestatsproto/jarjar-rules.txt @@ -0,0 +1 @@ +rule com.google.protobuf.nano.** com.android.framework.protobuf.nano.@1 diff --git a/services/surfaceflinger/TimeStats/timestatsproto/timestats.proto b/services/surfaceflinger/TimeStats/timestatsproto/timestats.proto new file mode 100644 index 0000000000..a8f6fa8ab1 --- /dev/null +++ b/services/surfaceflinger/TimeStats/timestatsproto/timestats.proto @@ -0,0 +1,69 @@ +/* + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +syntax = "proto2"; + +package android.surfaceflinger; + +option optimize_for = LITE_RUNTIME; + +// frameworks/base/core/proto/android/service/sftimestats.proto is based on +// this proto. Please only make valid protobuf changes to these messages, and +// keep the other file in sync with this one. + +message SFTimeStatsGlobalProto { + // The start & end timestamps in UTC as + // milliseconds since January 1, 1970 + optional int64 stats_start = 1; + optional int64 stats_end = 2; + // Total frames + optional int32 total_frames = 3; + // Total missed frames of SurfaceFlinger. + optional int32 missed_frames = 4; + // Total frames fallback to client composition. + optional int32 client_composition_frames = 5; + + repeated SFTimeStatsLayerProto stats = 6; +} + +message SFTimeStatsLayerProto { + // The layer name + optional string layer_name = 1; + // The package name + optional string package_name = 2; + // The start & end timestamps in UTC as + // milliseconds since January 1, 1970 + optional int64 stats_start = 3; + optional int64 stats_end = 4; + // Distinct frame count. + optional int32 total_frames = 5; + + repeated SFTimeStatsDeltaProto deltas = 6; +} + +message SFTimeStatsDeltaProto { + // Name of the time interval + optional string delta_name = 1; + // Histogram of the delta time + repeated SFTimeStatsHistogramBucketProto histograms = 2; +} + +message SFTimeStatsHistogramBucketProto { + // Lower bound of render time in milliseconds. + optional int32 render_millis = 1; + // Number of frames in the bucket. + optional int32 frame_count = 2; +} diff --git a/services/surfaceflinger/tests/Android.bp b/services/surfaceflinger/tests/Android.bp index 7523399dbf..322e8a0fea 100644 --- a/services/surfaceflinger/tests/Android.bp +++ b/services/surfaceflinger/tests/Android.bp @@ -36,6 +36,7 @@ cc_test { "liblayers_proto", "liblog", "libprotobuf-cpp-full", + "libtimestats_proto", "libui", "libutils", ] diff --git a/services/surfaceflinger/tests/fakehwc/Android.bp b/services/surfaceflinger/tests/fakehwc/Android.bp index 00bc621df0..520df2d63f 100644 --- a/services/surfaceflinger/tests/fakehwc/Android.bp +++ b/services/surfaceflinger/tests/fakehwc/Android.bp @@ -25,6 +25,7 @@ cc_test { "liblog", "libnativewindow", "libsync", + "libtimestats_proto", "libui", "libutils", ], -- cgit v1.2.3-59-g8ed1b From 1148147c4c06d9d5390c7b7c8b0ca5e0c245fc4a Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Fri, 4 May 2018 10:43:19 -0700 Subject: surfaceflinger: re-saturate all legacy dataspaces We changed HIDL interface to re-saturate any legacy dataspace. Update SurfaceFlinger to match the behavior. Bug: 78303195 Test: videos are re-saturated as well in GPU fallback Change-Id: Idfa74783061a62d79ca5d9f38e50f4095ce38322 --- services/surfaceflinger/BufferLayer.cpp | 21 +++++++++++++-------- services/surfaceflinger/Layer.cpp | 7 ++++--- services/surfaceflinger/Layer.h | 4 ++-- services/surfaceflinger/SurfaceFlinger.cpp | 2 +- 4 files changed, 20 insertions(+), 14 deletions(-) (limited to 'services/surfaceflinger/BufferLayer.cpp') diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index 4c3844e130..6feec53257 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -528,11 +528,9 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime recomputeVisibleRegions = true; } - // Dataspace::V0_SRGB and Dataspace::V0_SRGB_LINEAR are not legacy - // data space, however since framework doesn't distinguish them out of - // legacy SRGB, we have to treat them as the same for now. - // UNKNOWN is treated as legacy SRGB when the connected api is EGL. ui::Dataspace dataSpace = mConsumer->getCurrentDataSpace(); + // treat modern dataspaces as legacy dataspaces whenever possible, until + // we can trust the buffer producers switch (dataSpace) { case ui::Dataspace::V0_SRGB: dataSpace = ui::Dataspace::SRGB; @@ -540,10 +538,17 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime case ui::Dataspace::V0_SRGB_LINEAR: dataSpace = ui::Dataspace::SRGB_LINEAR; break; - case ui::Dataspace::UNKNOWN: - if (mConsumer->getCurrentApi() == NATIVE_WINDOW_API_EGL) { - dataSpace = ui::Dataspace::SRGB; - } + case ui::Dataspace::V0_JFIF: + dataSpace = ui::Dataspace::JFIF; + break; + case ui::Dataspace::V0_BT601_625: + dataSpace = ui::Dataspace::BT601_625; + break; + case ui::Dataspace::V0_BT601_525: + dataSpace = ui::Dataspace::BT601_525; + break; + case ui::Dataspace::V0_BT709: + dataSpace = ui::Dataspace::BT709; break; default: break; diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 2802fc7b21..9043234132 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -1650,9 +1650,10 @@ bool Layer::detachChildren() { return true; } -bool Layer::isLegacySrgbDataSpace() const { - return mDrawingState.dataSpace == ui::Dataspace::SRGB || - mDrawingState.dataSpace == ui::Dataspace::SRGB_LINEAR; +bool Layer::isLegacyDataSpace() const { + // return true when no higher bits are set + return !(mDrawingState.dataSpace & (ui::Dataspace::STANDARD_MASK | + ui::Dataspace::TRANSFER_MASK | ui::Dataspace::RANGE_MASK)); } void Layer::setParent(const sp& layer) { diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 0b15b67062..632efbe23e 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -303,8 +303,8 @@ public: // desaturated in order to match what they appears like visually. // With color management, these contents will appear desaturated, thus // needed to be saturated so that they match what they are designed for - // visually. When returns true, legacy SRGB data space is passed to HWC. - bool isLegacySrgbDataSpace() const; + // visually. + bool isLegacyDataSpace() const; // If we have received a new buffer this frame, we will pass its surface // damage down to hardware composer. Otherwise, we must send a region with diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index cdf7ccaacc..da6447624c 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -2989,7 +2989,7 @@ bool SurfaceFlinger::doComposeSurfaces(const sp& displayDev bool restore = false; mat4 savedMatrix; if (mDisplayColorSetting == DisplayColorSetting::ENHANCED && - layer->isLegacySrgbDataSpace()) { + layer->isLegacyDataSpace()) { savedMatrix = getRenderEngine().setupColorTransform(legacySrgbSaturationMatrix); restore = true; -- cgit v1.2.3-59-g8ed1b From 1b6bafca6e5c4a71bc97f14be30e64541633bda7 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Tue, 22 May 2018 12:03:00 -0700 Subject: surfaceflinger: layer dataspace is not a state Like current crop or transform, layer dataspace is latched with the buffer. It is not a layer state, and should take effect immediately. Bug: 80139629 Test: manual Change-Id: I52342ca345f174e647550b45defa977484db95a1 Merged-In: I52342ca345f174e647550b45defa977484db95a1 --- services/surfaceflinger/BufferLayer.cpp | 12 ++++++------ services/surfaceflinger/ColorLayer.cpp | 4 ++-- services/surfaceflinger/Layer.cpp | 20 +++++++------------- services/surfaceflinger/Layer.h | 5 +++-- services/surfaceflinger/SurfaceFlinger.cpp | 10 +++++----- 5 files changed, 23 insertions(+), 28 deletions(-) (limited to 'services/surfaceflinger/BufferLayer.cpp') diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index 6feec53257..17ed9aa00c 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -553,7 +553,7 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime default: break; } - setDataSpace(dataSpace); + mCurrentDataSpace = dataSpace; Rect crop(mConsumer->getCurrentCrop()); const uint32_t transform(mConsumer->getCurrentTransform()); @@ -660,10 +660,10 @@ void BufferLayer::setPerFrameData(const sp& displayDevice) setCompositionType(hwcId, HWC2::Composition::Device); } - ALOGV("setPerFrameData: dataspace = %d", mDrawingState.dataSpace); - error = hwcLayer->setDataspace(mDrawingState.dataSpace); + ALOGV("setPerFrameData: dataspace = %d", mCurrentDataSpace); + error = hwcLayer->setDataspace(mCurrentDataSpace); if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), mDrawingState.dataSpace, + ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), mCurrentDataSpace, to_string(error).c_str(), static_cast(error)); } @@ -866,9 +866,9 @@ void BufferLayer::drawWithOpenGL(const RenderArea& renderArea, bool useIdentityT auto& engine(mFlinger->getRenderEngine()); engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), false /* disableTexture */, getColor()); - engine.setSourceDataSpace(mCurrentState.dataSpace); + engine.setSourceDataSpace(mCurrentDataSpace); - if (mCurrentState.dataSpace == ui::Dataspace::BT2020_ITU_PQ && + if (mCurrentDataSpace == ui::Dataspace::BT2020_ITU_PQ && mConsumer->getCurrentApi() == NATIVE_WINDOW_API_MEDIA && getBE().compositionInfo.mBuffer->getPixelFormat() == HAL_PIXEL_FORMAT_RGBA_1010102) { engine.setSourceY410BT2020(true); diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp index c87b66981d..512564c2db 100644 --- a/services/surfaceflinger/ColorLayer.cpp +++ b/services/surfaceflinger/ColorLayer.cpp @@ -77,9 +77,9 @@ void ColorLayer::setPerFrameData(const sp& displayDevice) { setCompositionType(hwcId, HWC2::Composition::SolidColor); - error = hwcLayer->setDataspace(mDrawingState.dataSpace); + error = hwcLayer->setDataspace(mCurrentDataSpace); if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), mDrawingState.dataSpace, + ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), mCurrentDataSpace, to_string(error).c_str(), static_cast(error)); } diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 2077598371..b94af77967 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -123,7 +123,6 @@ Layer::Layer(SurfaceFlinger* flinger, const sp& client, const String8& n mCurrentState.layerStack = 0; mCurrentState.sequence = 0; mCurrentState.requested = mCurrentState.active; - mCurrentState.dataSpace = ui::Dataspace::UNKNOWN; mCurrentState.appId = 0; mCurrentState.type = 0; @@ -1328,15 +1327,6 @@ bool Layer::setLayerStack(uint32_t layerStack) { return true; } -bool Layer::setDataSpace(ui::Dataspace dataSpace) { - if (mCurrentState.dataSpace == dataSpace) return false; - mCurrentState.sequence++; - mCurrentState.dataSpace = dataSpace; - mCurrentState.modified = true; - setTransactionFlags(eTransactionNeeded); - return true; -} - uint32_t Layer::getLayerStack() const { auto p = mDrawingParent.promote(); if (p == nullptr) { @@ -1429,7 +1419,7 @@ LayerDebugInfo Layer::getLayerDebugInfo() const { info.mColor = ds.color; info.mFlags = ds.flags; info.mPixelFormat = getPixelFormat(); - info.mDataSpace = static_cast(ds.dataSpace); + info.mDataSpace = static_cast(mCurrentDataSpace); info.mMatrix[0][0] = ds.active.transform[0][0]; info.mMatrix[0][1] = ds.active.transform[0][1]; info.mMatrix[1][0] = ds.active.transform[1][0]; @@ -1648,7 +1638,7 @@ bool Layer::detachChildren() { bool Layer::isLegacyDataSpace() const { // return true when no higher bits are set - return !(mDrawingState.dataSpace & (ui::Dataspace::STANDARD_MASK | + return !(mCurrentDataSpace & (ui::Dataspace::STANDARD_MASK | ui::Dataspace::TRANSFER_MASK | ui::Dataspace::RANGE_MASK)); } @@ -1956,7 +1946,10 @@ void Layer::writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet) layerInfo->set_is_opaque(isOpaque(state)); layerInfo->set_invalidate(contentDirty); - layerInfo->set_dataspace(dataspaceDetails(static_cast(state.dataSpace))); + + // XXX (b/79210409) mCurrentDataSpace is not protected + layerInfo->set_dataspace(dataspaceDetails(static_cast(mCurrentDataSpace))); + layerInfo->set_pixel_format(decodePixelFormat(getPixelFormat())); LayerProtoHelper::writeToProto(getColor(), layerInfo->mutable_color()); LayerProtoHelper::writeToProto(state.color, layerInfo->mutable_requested_color()); @@ -1975,6 +1968,7 @@ void Layer::writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet) layerInfo->set_z_order_relative_of(zOrderRelativeOf->sequence); } + // XXX getBE().compositionInfo.mBuffer is not protected auto buffer = getBE().compositionInfo.mBuffer; if (buffer != nullptr) { LayerProtoHelper::writeToProto(buffer, layerInfo->mutable_active_buffer()); diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 91eb15ae4a..7342c8b987 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -209,7 +209,6 @@ public: // dependent. Region activeTransparentRegion; Region requestedTransparentRegion; - ui::Dataspace dataSpace; int32_t appId; int32_t type; @@ -287,7 +286,6 @@ public: bool setTransparentRegionHint(const Region& transparent); bool setFlags(uint8_t flags, uint8_t mask); bool setLayerStack(uint32_t layerStack); - bool setDataSpace(ui::Dataspace dataSpace); uint32_t getLayerStack() const; void deferTransactionUntil(const sp& barrierHandle, uint64_t frameNumber); void deferTransactionUntil(const sp& barrierLayer, uint64_t frameNumber); @@ -298,6 +296,8 @@ public: bool reparent(const sp& newParentHandle); bool detachChildren(); + ui::Dataspace getDataSpace() const { return mCurrentDataSpace; } + // Before color management is introduced, contents on Android have to be // desaturated in order to match what they appears like visually. // With color management, these contents will appear desaturated, thus @@ -743,6 +743,7 @@ protected: int mActiveBufferSlot; sp mActiveBuffer; sp mSidebandStream; + ui::Dataspace mCurrentDataSpace = ui::Dataspace::UNKNOWN; Rect mCurrentCrop; uint32_t mCurrentTransform; // We encode unset as -1. diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 9117207544..e7892ef109 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -1879,7 +1879,7 @@ Dataspace SurfaceFlinger::getBestDataspace( *outHdrDataSpace = Dataspace::UNKNOWN; for (const auto& layer : displayDevice->getVisibleLayersSortedByZ()) { - switch (layer->getDrawingState().dataSpace) { + switch (layer->getDataSpace()) { case Dataspace::V0_SCRGB: case Dataspace::V0_SCRGB_LINEAR: bestDataSpace = Dataspace::V0_SCRGB_LINEAR; @@ -2098,13 +2098,13 @@ void SurfaceFlinger::setUpHWComposer() { "display %zd: %d", displayId, result); } for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { - if ((layer->getDrawingState().dataSpace == Dataspace::BT2020_PQ || - layer->getDrawingState().dataSpace == Dataspace::BT2020_ITU_PQ) && + if ((layer->getDataSpace() == Dataspace::BT2020_PQ || + layer->getDataSpace() == Dataspace::BT2020_ITU_PQ) && !displayDevice->hasHDR10Support()) { layer->forceClientComposition(hwcId); } - if ((layer->getDrawingState().dataSpace == Dataspace::BT2020_HLG || - layer->getDrawingState().dataSpace == Dataspace::BT2020_ITU_HLG) && + if ((layer->getDataSpace() == Dataspace::BT2020_HLG || + layer->getDataSpace() == Dataspace::BT2020_ITU_HLG) && !displayDevice->hasHLGSupport()) { layer->forceClientComposition(hwcId); } -- cgit v1.2.3-59-g8ed1b From 07376a98a6c66c4e48bdebe82616f0ae47e5f805 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Tue, 5 Jun 2018 15:46:58 -0700 Subject: surfaceflinger: force client composition for Y410 When the pixel format is Y410 masquerading as RGBA_1010102, always force client composition. Bug: 80509363 Test: no effect on Pixel devices Change-Id: I31996eeda1559b0557a5acb53d593fd4f395ccaf Merged-In: I31996eeda1559b0557a5acb53d593fd4f395ccaf --- services/surfaceflinger/BufferLayer.cpp | 11 ++++++++--- services/surfaceflinger/BufferLayer.h | 2 ++ services/surfaceflinger/Layer.h | 2 ++ services/surfaceflinger/SurfaceFlinger.cpp | 11 ++++++----- 4 files changed, 18 insertions(+), 8 deletions(-) (limited to 'services/surfaceflinger/BufferLayer.cpp') diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index 17ed9aa00c..fda7906744 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -815,6 +815,13 @@ bool BufferLayer::getOpacityForFormat(uint32_t format) { return true; } +bool BufferLayer::isHdrY410() const { + // pixel format is HDR Y410 masquerading as RGBA_1010102 + return (mCurrentDataSpace == ui::Dataspace::BT2020_ITU_PQ && + mConsumer->getCurrentApi() == NATIVE_WINDOW_API_MEDIA && + getBE().compositionInfo.mBuffer->getPixelFormat() == HAL_PIXEL_FORMAT_RGBA_1010102); +} + void BufferLayer::drawWithOpenGL(const RenderArea& renderArea, bool useIdentityTransform) const { ATRACE_CALL(); const State& s(getDrawingState()); @@ -868,9 +875,7 @@ void BufferLayer::drawWithOpenGL(const RenderArea& renderArea, bool useIdentityT getColor()); engine.setSourceDataSpace(mCurrentDataSpace); - if (mCurrentDataSpace == ui::Dataspace::BT2020_ITU_PQ && - mConsumer->getCurrentApi() == NATIVE_WINDOW_API_MEDIA && - getBE().compositionInfo.mBuffer->getPixelFormat() == HAL_PIXEL_FORMAT_RGBA_1010102) { + if (isHdrY410()) { engine.setSourceY410BT2020(true); } diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h index 6b02f8c128..bf0ca69253 100644 --- a/services/surfaceflinger/BufferLayer.h +++ b/services/surfaceflinger/BufferLayer.h @@ -129,6 +129,8 @@ public: bool isBufferLatched() const override { return mRefreshPending; } void setDefaultBufferSize(uint32_t w, uint32_t h) override; + bool isHdrY410() const override; + void setPerFrameData(const sp& displayDevice) override; bool isOpaque(const Layer::State& s) const override; diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index ae80043a5d..34811fb152 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -378,6 +378,8 @@ protected: public: virtual void setDefaultBufferSize(uint32_t /*w*/, uint32_t /*h*/) {} + virtual bool isHdrY410() const { return false; } + void setGeometry(const sp& displayDevice, uint32_t z); void forceClientComposition(int32_t hwcId); bool getForceClientComposition(int32_t hwcId); diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 97edd357ed..c97ae19315 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -2031,13 +2031,14 @@ void SurfaceFlinger::setUpHWComposer() { "display %zd: %d", displayId, result); } for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) { - if ((layer->getDataSpace() == Dataspace::BT2020_PQ || - layer->getDataSpace() == Dataspace::BT2020_ITU_PQ) && + if (layer->isHdrY410()) { + layer->forceClientComposition(hwcId); + } else if ((layer->getDataSpace() == Dataspace::BT2020_PQ || + layer->getDataSpace() == Dataspace::BT2020_ITU_PQ) && !displayDevice->hasHDR10Support()) { layer->forceClientComposition(hwcId); - } - if ((layer->getDataSpace() == Dataspace::BT2020_HLG || - layer->getDataSpace() == Dataspace::BT2020_ITU_HLG) && + } else if ((layer->getDataSpace() == Dataspace::BT2020_HLG || + layer->getDataSpace() == Dataspace::BT2020_ITU_HLG) && !displayDevice->hasHLGSupport()) { layer->forceClientComposition(hwcId); } -- cgit v1.2.3-59-g8ed1b