blob: 80004a10becd2baeac81cf08152efea395ab2776 [file] [log] [blame]
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Dan Stoza9e56aa02015-11-02 13:00:03 -080017// #define LOG_NDEBUG 0
18#undef LOG_TAG
19#define LOG_TAG "DisplayDevice"
20
Peiyong Lincbc184f2018-08-22 13:24:10 -070021#include "DisplayDevice.h"
22
Chia-I Wube02ec02018-05-18 10:59:36 -070023#include <array>
24#include <unordered_set>
25
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080026#include <stdlib.h>
27#include <stdio.h>
28#include <string.h>
29#include <math.h>
30
Dominik Laskowski9b17b2c22018-11-01 14:49:03 -070031#include <android-base/stringprintf.h>
Peiyong Lincbc184f2018-08-22 13:24:10 -070032#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
Lloyd Pique45a165a2018-10-19 11:54:47 -070033#include <compositionengine/CompositionEngine.h>
34#include <compositionengine/Display.h>
35#include <compositionengine/DisplayCreationArgs.h>
Lloyd Pique542307f2018-10-19 13:24:08 -070036#include <compositionengine/DisplaySurface.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070037#include <compositionengine/impl/OutputCompositionState.h>
Peiyong Lincbc184f2018-08-22 13:24:10 -070038#include <configstore/Utils.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080039#include <cutils/properties.h>
Peiyong Lincbc184f2018-08-22 13:24:10 -070040#include <gui/Surface.h>
41#include <hardware/gralloc.h>
42#include <renderengine/RenderEngine.h>
Alec Mouri0a9c7b82018-11-16 13:05:25 -080043#include <sync/sync.h>
44#include <system/window.h>
Courtney Goeltzenleuchter152279d2017-08-14 18:18:30 -060045#include <ui/DebugUtils.h>
Mathias Agopianc666cae2012-07-25 18:56:13 -070046#include <ui/DisplayInfo.h>
Mathias Agopian076b1cc2009-04-10 14:24:30 -070047#include <ui/PixelFormat.h>
Peiyong Lincbc184f2018-08-22 13:24:10 -070048#include <utils/Log.h>
Valerie Hau9758ae02018-10-09 16:05:09 -070049#include <utils/RefBase.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080050
Mathias Agopian1b031492012-06-20 17:51:20 -070051#include "DisplayHardware/HWComposer.h"
Dan Stoza9e56aa02015-11-02 13:00:03 -080052#include "DisplayHardware/HWC2.h"
Mathias Agopianc7d14e22011-08-01 16:32:21 -070053#include "SurfaceFlinger.h"
Mathias Agopian13127d82013-03-05 17:47:11 -080054#include "Layer.h"
Mathias Agopian1f7bec62010-06-25 18:02:21 -070055
Peiyong Linfd997e02018-03-28 15:29:00 -070056namespace android {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080057
Jaesoo Lee720a7242017-01-31 15:26:18 +090058// retrieve triple buffer setting from configstore
59using namespace android::hardware::configstore;
60using namespace android::hardware::configstore::V1_0;
Yiwei Zhang5434a782018-12-05 18:06:32 -080061using android::base::StringAppendF;
Peiyong Linfd997e02018-03-28 15:29:00 -070062using android::ui::ColorMode;
Chia-I Wube02ec02018-05-18 10:59:36 -070063using android::ui::Dataspace;
Peiyong Lin62665892018-04-16 11:07:44 -070064using android::ui::Hdr;
Peiyong Lindd9b2ae2018-03-01 16:22:45 -080065using android::ui::RenderIntent;
Jaesoo Lee720a7242017-01-31 15:26:18 +090066
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080067/*
68 * Initialize the display to the specified values.
69 *
70 */
71
Pablo Ceballos021623b2016-04-15 17:31:51 -070072uint32_t DisplayDevice::sPrimaryDisplayOrientation = 0;
73
Chia-I Wube02ec02018-05-18 10:59:36 -070074namespace {
75
76// ordered list of known SDR color modes
Valerie Hau9758ae02018-10-09 16:05:09 -070077const std::array<ColorMode, 3> sSdrColorModes = {
78 ColorMode::DISPLAY_BT2020,
Chia-I Wube02ec02018-05-18 10:59:36 -070079 ColorMode::DISPLAY_P3,
80 ColorMode::SRGB,
81};
82
83// ordered list of known HDR color modes
84const std::array<ColorMode, 2> sHdrColorModes = {
85 ColorMode::BT2100_PQ,
86 ColorMode::BT2100_HLG,
87};
88
89// ordered list of known SDR render intents
90const std::array<RenderIntent, 2> sSdrRenderIntents = {
91 RenderIntent::ENHANCE,
92 RenderIntent::COLORIMETRIC,
93};
94
95// ordered list of known HDR render intents
96const std::array<RenderIntent, 2> sHdrRenderIntents = {
97 RenderIntent::TONE_MAP_ENHANCE,
98 RenderIntent::TONE_MAP_COLORIMETRIC,
99};
100
101// map known color mode to dataspace
102Dataspace colorModeToDataspace(ColorMode mode) {
103 switch (mode) {
104 case ColorMode::SRGB:
Peiyong Lin14724e62018-12-05 07:27:30 -0800105 return Dataspace::V0_SRGB;
Chia-I Wube02ec02018-05-18 10:59:36 -0700106 case ColorMode::DISPLAY_P3:
107 return Dataspace::DISPLAY_P3;
Valerie Hau9758ae02018-10-09 16:05:09 -0700108 case ColorMode::DISPLAY_BT2020:
109 return Dataspace::DISPLAY_BT2020;
Chia-I Wube02ec02018-05-18 10:59:36 -0700110 case ColorMode::BT2100_HLG:
111 return Dataspace::BT2020_HLG;
112 case ColorMode::BT2100_PQ:
113 return Dataspace::BT2020_PQ;
114 default:
115 return Dataspace::UNKNOWN;
116 }
117}
118
119// Return a list of candidate color modes.
120std::vector<ColorMode> getColorModeCandidates(ColorMode mode) {
121 std::vector<ColorMode> candidates;
122
123 // add mode itself
124 candidates.push_back(mode);
125
126 // check if mode is HDR
127 bool isHdr = false;
128 for (auto hdrMode : sHdrColorModes) {
129 if (hdrMode == mode) {
130 isHdr = true;
131 break;
132 }
133 }
134
135 // add other HDR candidates when mode is HDR
136 if (isHdr) {
137 for (auto hdrMode : sHdrColorModes) {
138 if (hdrMode != mode) {
139 candidates.push_back(hdrMode);
140 }
141 }
142 }
143
144 // add other SDR candidates
145 for (auto sdrMode : sSdrColorModes) {
146 if (sdrMode != mode) {
147 candidates.push_back(sdrMode);
148 }
149 }
150
151 return candidates;
152}
153
154// Return a list of candidate render intents.
155std::vector<RenderIntent> getRenderIntentCandidates(RenderIntent intent) {
156 std::vector<RenderIntent> candidates;
157
158 // add intent itself
159 candidates.push_back(intent);
160
161 // check if intent is HDR
162 bool isHdr = false;
163 for (auto hdrIntent : sHdrRenderIntents) {
164 if (hdrIntent == intent) {
165 isHdr = true;
166 break;
167 }
168 }
169
Chia-I Wube02ec02018-05-18 10:59:36 -0700170 if (isHdr) {
Chia-I Wuc4b08bd2018-05-29 12:57:23 -0700171 // add other HDR candidates when intent is HDR
Chia-I Wube02ec02018-05-18 10:59:36 -0700172 for (auto hdrIntent : sHdrRenderIntents) {
173 if (hdrIntent != intent) {
174 candidates.push_back(hdrIntent);
175 }
176 }
Chia-I Wuc4b08bd2018-05-29 12:57:23 -0700177 } else {
178 // add other SDR candidates when intent is SDR
179 for (auto sdrIntent : sSdrRenderIntents) {
180 if (sdrIntent != intent) {
181 candidates.push_back(sdrIntent);
182 }
183 }
Chia-I Wube02ec02018-05-18 10:59:36 -0700184 }
185
186 return candidates;
187}
188
189// Return the best color mode supported by HWC.
190ColorMode getHwcColorMode(
191 const std::unordered_map<ColorMode, std::vector<RenderIntent>>& hwcColorModes,
192 ColorMode mode) {
193 std::vector<ColorMode> candidates = getColorModeCandidates(mode);
194 for (auto candidate : candidates) {
195 auto iter = hwcColorModes.find(candidate);
196 if (iter != hwcColorModes.end()) {
197 return candidate;
198 }
199 }
200
201 return ColorMode::NATIVE;
202}
203
204// Return the best render intent supported by HWC.
205RenderIntent getHwcRenderIntent(const std::vector<RenderIntent>& hwcIntents, RenderIntent intent) {
206 std::vector<RenderIntent> candidates = getRenderIntentCandidates(intent);
207 for (auto candidate : candidates) {
208 for (auto hwcIntent : hwcIntents) {
209 if (candidate == hwcIntent) {
210 return candidate;
211 }
212 }
213 }
214
215 return RenderIntent::COLORIMETRIC;
216}
217
218} // anonymous namespace
219
Lloyd Pique2eef1d22018-09-18 21:30:04 -0700220DisplayDeviceCreationArgs::DisplayDeviceCreationArgs(const sp<SurfaceFlinger>& flinger,
221 const wp<IBinder>& displayToken,
Dominik Laskowski075d3172018-05-24 15:50:06 -0700222 const std::optional<DisplayId>& displayId)
223 : flinger(flinger), displayToken(displayToken), displayId(displayId) {}
Chia-I Wube02ec02018-05-18 10:59:36 -0700224
Lloyd Pique2eef1d22018-09-18 21:30:04 -0700225DisplayDevice::DisplayDevice(DisplayDeviceCreationArgs&& args)
Lloyd Pique32cbe282018-10-19 13:09:22 -0700226 : mFlinger(args.flinger),
Lloyd Pique2eef1d22018-09-18 21:30:04 -0700227 mDisplayToken(args.displayToken),
Dominik Laskowskie9774092018-12-11 10:04:24 -0800228 mSequenceId(args.sequenceId),
Lloyd Pique45a165a2018-10-19 11:54:47 -0700229 mDisplayInstallOrientation(args.displayInstallOrientation),
230 mCompositionDisplay{mFlinger->getCompositionEngine().createDisplay(
231 compositionengine::DisplayCreationArgs{args.isSecure, args.isVirtual,
232 args.displayId})},
Lloyd Pique2eef1d22018-09-18 21:30:04 -0700233 mNativeWindow(args.nativeWindow),
Alec Mouri0a9c7b82018-11-16 13:05:25 -0800234 mGraphicBuffer(nullptr),
Lloyd Pique2eef1d22018-09-18 21:30:04 -0700235 mDisplaySurface(args.displaySurface),
Lloyd Pique2eef1d22018-09-18 21:30:04 -0700236 mPageFlipCount(0),
Dominik Laskowski075d3172018-05-24 15:50:06 -0700237 mIsVirtual(args.isVirtual),
Lloyd Pique2eef1d22018-09-18 21:30:04 -0700238 mOrientation(),
Lloyd Pique2eef1d22018-09-18 21:30:04 -0700239 mActiveConfig(0),
Lloyd Pique2eef1d22018-09-18 21:30:04 -0700240 mHasWideColorGamut(args.hasWideColorGamut),
Valerie Haue9e843a2018-12-18 13:39:23 -0800241 mHasHdr10Plus(false),
Lloyd Pique2eef1d22018-09-18 21:30:04 -0700242 mHasHdr10(false),
243 mHasHLG(false),
244 mHasDolbyVision(false),
Dominik Laskowski075d3172018-05-24 15:50:06 -0700245 mSupportedPerFrameMetadata(args.supportedPerFrameMetadata),
246 mIsPrimary(args.isPrimary) {
Lloyd Pique32cbe282018-10-19 13:09:22 -0700247 if (!mCompositionDisplay->isValid()) {
248 ALOGE("Composition Display did not validate!");
249 }
250
Lloyd Pique2eef1d22018-09-18 21:30:04 -0700251 populateColorModes(args.hwcColorModes);
252
253 ALOGE_IF(!mNativeWindow, "No native window was set for display");
254 ALOGE_IF(!mDisplaySurface, "No display surface was set for display");
Lloyd Pique2eef1d22018-09-18 21:30:04 -0700255
256 std::vector<Hdr> types = args.hdrCapabilities.getSupportedHdrTypes();
Peiyong Linfb069302018-04-25 14:34:31 -0700257 for (Hdr hdrType : types) {
Peiyong Lin62665892018-04-16 11:07:44 -0700258 switch (hdrType) {
Valerie Haue9e843a2018-12-18 13:39:23 -0800259 case Hdr::HDR10_PLUS:
260 mHasHdr10Plus = true;
261 break;
Peiyong Lin62665892018-04-16 11:07:44 -0700262 case Hdr::HDR10:
263 mHasHdr10 = true;
264 break;
265 case Hdr::HLG:
266 mHasHLG = true;
267 break;
268 case Hdr::DOLBY_VISION:
269 mHasDolbyVision = true;
270 break;
271 default:
272 ALOGE("UNKNOWN HDR capability: %d", static_cast<int32_t>(hdrType));
273 }
274 }
Jesse Hallffe1f192013-03-22 15:13:48 -0700275
Lloyd Pique2eef1d22018-09-18 21:30:04 -0700276 float minLuminance = args.hdrCapabilities.getDesiredMinLuminance();
277 float maxLuminance = args.hdrCapabilities.getDesiredMaxLuminance();
278 float maxAverageLuminance = args.hdrCapabilities.getDesiredMaxAverageLuminance();
Peiyong Linfb069302018-04-25 14:34:31 -0700279
280 minLuminance = minLuminance <= 0.0 ? sDefaultMinLumiance : minLuminance;
281 maxLuminance = maxLuminance <= 0.0 ? sDefaultMaxLumiance : maxLuminance;
282 maxAverageLuminance = maxAverageLuminance <= 0.0 ? sDefaultMaxLumiance : maxAverageLuminance;
283 if (this->hasWideColorGamut()) {
284 // insert HDR10/HLG as we will force client composition for HDR10/HLG
285 // layers
286 if (!hasHDR10Support()) {
Valerie Haue9e843a2018-12-18 13:39:23 -0800287 types.push_back(Hdr::HDR10);
Peiyong Linfb069302018-04-25 14:34:31 -0700288 }
289
290 if (!hasHLGSupport()) {
Valerie Haue9e843a2018-12-18 13:39:23 -0800291 types.push_back(Hdr::HLG);
Peiyong Linfb069302018-04-25 14:34:31 -0700292 }
293 }
294 mHdrCapabilities = HdrCapabilities(types, maxLuminance, maxAverageLuminance, minLuminance);
295
Alec Mouriba013fa2018-10-16 12:43:11 -0700296 ANativeWindow* const window = mNativeWindow.get();
Alec Mouri0a9c7b82018-11-16 13:05:25 -0800297
Alec Mouri4efb6c22018-11-16 13:07:47 -0800298 int status = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
Alec Mouri0a9c7b82018-11-16 13:05:25 -0800299 ALOGE_IF(status != NO_ERROR, "Unable to connect BQ producer: %d", status);
Alec Mouri4efb6c22018-11-16 13:07:47 -0800300 status = native_window_set_buffers_format(window, HAL_PIXEL_FORMAT_RGBA_8888);
301 ALOGE_IF(status != NO_ERROR, "Unable to set BQ format to RGBA888: %d", status);
302 status = native_window_set_usage(window, GRALLOC_USAGE_HW_RENDER);
303 ALOGE_IF(status != NO_ERROR, "Unable to set BQ usage bits for GPU rendering: %d", status);
Alec Mouri0a9c7b82018-11-16 13:05:25 -0800304
Lloyd Pique32cbe282018-10-19 13:09:22 -0700305 mCompositionDisplay->setBounds(
306 Rect(ANativeWindow_getWidth(window), ANativeWindow_getHeight(window)));
307
308 setPowerMode(args.initialPowerMode);
Alec Mouriba013fa2018-10-16 12:43:11 -0700309
Jesse Hallffe1f192013-03-22 15:13:48 -0700310 // initialize the display orientation transform.
Lloyd Pique32cbe282018-10-19 13:09:22 -0700311 setProjection(DisplayState::eOrientationDefault, Rect::INVALID_RECT, Rect::INVALID_RECT);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800312}
313
Lloyd Pique09594832018-01-22 17:48:03 -0800314DisplayDevice::~DisplayDevice() = default;
Mathias Agopian92a979a2012-08-02 18:32:23 -0700315
Lloyd Pique45a165a2018-10-19 11:54:47 -0700316void DisplayDevice::disconnect() {
317 mCompositionDisplay->disconnect();
Jesse Hall02d86562013-03-25 14:43:23 -0700318}
319
Mathias Agopian0f2f5ff2012-07-31 23:09:07 -0700320int DisplayDevice::getWidth() const {
Lloyd Pique32cbe282018-10-19 13:09:22 -0700321 return mCompositionDisplay->getState().bounds.getWidth();
Mathias Agopiana4912602012-07-12 14:25:33 -0700322}
323
Mathias Agopian0f2f5ff2012-07-31 23:09:07 -0700324int DisplayDevice::getHeight() const {
Lloyd Pique32cbe282018-10-19 13:09:22 -0700325 return mCompositionDisplay->getState().bounds.getHeight();
Mathias Agopiana4912602012-07-12 14:25:33 -0700326}
327
Dominik Laskowskibf170d92018-04-19 15:08:05 -0700328void DisplayDevice::setDisplayName(const std::string& displayName) {
329 if (!displayName.empty()) {
Mathias Agopian9e2463e2012-09-21 18:26:16 -0700330 // never override the name with an empty name
331 mDisplayName = displayName;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700332 mCompositionDisplay->setName(displayName);
Mathias Agopian9e2463e2012-09-21 18:26:16 -0700333 }
334}
335
Mathias Agopian0f2f5ff2012-07-31 23:09:07 -0700336uint32_t DisplayDevice::getPageFlipCount() const {
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700337 return mPageFlipCount;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800338}
339
Chia-I Wub02087d2017-11-09 10:19:54 -0800340void DisplayDevice::flip() const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800341{
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700342 mPageFlipCount++;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800343}
344
Dan Stoza71433162014-02-04 16:22:36 -0800345status_t DisplayDevice::beginFrame(bool mustRecompose) const {
346 return mDisplaySurface->beginFrame(mustRecompose);
Jesse Hall028dc8f2013-08-20 16:35:32 -0700347}
348
David Sodmanfb95bcc2017-12-22 15:45:30 -0800349status_t DisplayDevice::prepareFrame(HWComposer& hwc,
350 std::vector<CompositionInfo>& compositionData) {
Lloyd Pique45a165a2018-10-19 11:54:47 -0700351 const auto id = getId();
352 if (id) {
353 status_t error = hwc.prepare(id.value(), compositionData);
Dominik Laskowski075d3172018-05-24 15:50:06 -0700354 if (error != NO_ERROR) {
355 return error;
356 }
Dan Stoza9e56aa02015-11-02 13:00:03 -0800357 }
358
Lloyd Pique542307f2018-10-19 13:24:08 -0700359 compositionengine::DisplaySurface::CompositionType compositionType;
Lloyd Pique45a165a2018-10-19 11:54:47 -0700360 bool hasClient = hwc.hasClientComposition(id);
361 bool hasDevice = hwc.hasDeviceComposition(id);
Dan Stoza9e56aa02015-11-02 13:00:03 -0800362 if (hasClient && hasDevice) {
Lloyd Pique542307f2018-10-19 13:24:08 -0700363 compositionType = compositionengine::DisplaySurface::COMPOSITION_MIXED;
Dan Stoza9e56aa02015-11-02 13:00:03 -0800364 } else if (hasClient) {
Lloyd Pique542307f2018-10-19 13:24:08 -0700365 compositionType = compositionengine::DisplaySurface::COMPOSITION_GLES;
Dan Stoza9e56aa02015-11-02 13:00:03 -0800366 } else if (hasDevice) {
Lloyd Pique542307f2018-10-19 13:24:08 -0700367 compositionType = compositionengine::DisplaySurface::COMPOSITION_HWC;
Dan Stoza9e56aa02015-11-02 13:00:03 -0800368 } else {
369 // Nothing to do -- when turning the screen off we get a frame like
370 // this. Call it a HWC frame since we won't be doing any GLES work but
371 // will do a prepare/set cycle.
Lloyd Pique542307f2018-10-19 13:24:08 -0700372 compositionType = compositionengine::DisplaySurface::COMPOSITION_HWC;
Dan Stoza9e56aa02015-11-02 13:00:03 -0800373 }
374 return mDisplaySurface->prepareFrame(compositionType);
375}
Jesse Hall38efe862013-04-06 23:12:29 -0700376
Peiyong Linfb530cf2018-12-15 05:07:38 +0000377void DisplayDevice::setProtected(bool useProtected) {
378 uint64_t usageFlags = GRALLOC_USAGE_HW_RENDER;
379 if (useProtected) {
380 usageFlags |= GRALLOC_USAGE_PROTECTED;
381 }
382 const int status = native_window_set_usage(mNativeWindow.get(), usageFlags);
383 ALOGE_IF(status != NO_ERROR, "Unable to set BQ usage bits for protected content: %d", status);
384}
385
Alec Mouri0a9c7b82018-11-16 13:05:25 -0800386sp<GraphicBuffer> DisplayDevice::dequeueBuffer() {
387 int fd;
388 ANativeWindowBuffer* buffer;
389
390 status_t res = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buffer, &fd);
391
392 if (res != NO_ERROR) {
393 ALOGE("ANativeWindow::dequeueBuffer failed for display [%s] with error: %d",
394 getDisplayName().c_str(), res);
395 // Return fast here as we can't do much more - any rendering we do
396 // now will just be wrong.
397 return mGraphicBuffer;
398 }
399
400 ALOGW_IF(mGraphicBuffer != nullptr, "Clobbering a non-null pointer to a buffer [%p].",
401 mGraphicBuffer->getNativeBuffer()->handle);
402 mGraphicBuffer = GraphicBuffer::from(buffer);
403
404 // Block until the buffer is ready
405 // TODO(alecmouri): it's perhaps more appropriate to block renderengine so
406 // that the gl driver can block instead.
407 if (fd >= 0) {
408 sync_wait(fd, -1);
409 close(fd);
410 }
411
412 return mGraphicBuffer;
413}
414
415void DisplayDevice::queueBuffer(HWComposer& hwc) {
Lloyd Pique45a165a2018-10-19 11:54:47 -0700416 const auto id = getId();
417 if (hwc.hasClientComposition(id) || hwc.hasFlipClientTargetRequest(id)) {
Alec Mouri0a9c7b82018-11-16 13:05:25 -0800418 // hasFlipClientTargetRequest could return true even if we haven't
419 // dequeued a buffer before. Try dequeueing one if we don't have a
420 // buffer ready.
421 if (mGraphicBuffer == nullptr) {
422 ALOGI("Attempting to queue a client composited buffer without one "
423 "previously dequeued for display [%s]. Attempting to dequeue "
424 "a scratch buffer now",
425 mDisplayName.c_str());
426 // We shouldn't deadlock here, since mGraphicBuffer == nullptr only
427 // after a successful call to queueBuffer, or if dequeueBuffer has
428 // never been called.
429 dequeueBuffer();
430 }
431
432 if (mGraphicBuffer == nullptr) {
433 ALOGE("No buffer is ready for display [%s]", mDisplayName.c_str());
434 } else {
Alec Mouri0a9c7b82018-11-16 13:05:25 -0800435 status_t res = mNativeWindow->queueBuffer(mNativeWindow.get(),
Alec Mouri745163a2018-12-04 15:15:50 -0800436 mGraphicBuffer->getNativeBuffer(),
437 dup(mBufferReady));
Alec Mouri0a9c7b82018-11-16 13:05:25 -0800438 if (res != NO_ERROR) {
439 ALOGE("Error when queueing buffer for display [%s]: %d", mDisplayName.c_str(), res);
440 // We risk blocking on dequeueBuffer if the primary display failed
441 // to queue up its buffer, so crash here.
442 if (isPrimary()) {
443 LOG_ALWAYS_FATAL("ANativeWindow::queueBuffer failed with error: %d", res);
444 } else {
445 mNativeWindow->cancelBuffer(mNativeWindow.get(),
Alec Mouri745163a2018-12-04 15:15:50 -0800446 mGraphicBuffer->getNativeBuffer(),
447 dup(mBufferReady));
Alec Mouri0a9c7b82018-11-16 13:05:25 -0800448 }
449 }
Alec Mouri745163a2018-12-04 15:15:50 -0800450
451 mBufferReady.reset();
Alec Mouri0a9c7b82018-11-16 13:05:25 -0800452 mGraphicBuffer = nullptr;
453 }
Mathias Agopianda27af92012-09-13 18:17:13 -0700454 }
Mathias Agopian52e21482012-09-24 18:07:21 -0700455
Jesse Hall99c7dbb2013-03-14 14:29:29 -0700456 status_t result = mDisplaySurface->advanceFrame();
457 if (result != NO_ERROR) {
Dominik Laskowskibf170d92018-04-19 15:08:05 -0700458 ALOGE("[%s] failed pushing new frame to HWC: %d", mDisplayName.c_str(), result);
Mathias Agopian32341382012-09-25 19:16:28 -0700459 }
Mathias Agopianda27af92012-09-13 18:17:13 -0700460}
461
Alec Mouri0a9c7b82018-11-16 13:05:25 -0800462void DisplayDevice::onPresentDisplayCompleted() {
Dan Stoza9e56aa02015-11-02 13:00:03 -0800463 mDisplaySurface->onFrameCommitted();
464}
Mathias Agopianda27af92012-09-13 18:17:13 -0700465
Mathias Agopian875d8e12013-06-07 15:35:48 -0700466void DisplayDevice::setViewportAndProjection() const {
Lloyd Pique32cbe282018-10-19 13:09:22 -0700467 size_t w = getWidth();
468 size_t h = getHeight();
Dan Stozac1879002014-05-22 15:59:05 -0700469 Rect sourceCrop(0, 0, w, h);
Chia-I Wu1be50b52018-08-29 10:44:48 -0700470 mFlinger->getRenderEngine().setViewportAndProjection(w, h, sourceCrop, ui::Transform::ROT_0);
Mathias Agopianbae92d02012-09-28 01:00:47 -0700471}
472
Alec Mouri0a9c7b82018-11-16 13:05:25 -0800473void DisplayDevice::finishBuffer() {
474 mBufferReady = mFlinger->getRenderEngine().flush();
475 if (mBufferReady.get() < 0) {
476 mFlinger->getRenderEngine().finish();
477 }
478}
479
Dan Stoza9e56aa02015-11-02 13:00:03 -0800480const sp<Fence>& DisplayDevice::getClientTargetAcquireFence() const {
481 return mDisplaySurface->getClientTargetAcquireFence();
482}
Dan Stoza9e56aa02015-11-02 13:00:03 -0800483
Mathias Agopian1b031492012-06-20 17:51:20 -0700484// ----------------------------------------------------------------------------
485
Mathias Agopian13127d82013-03-05 17:47:11 -0800486void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers) {
Mathias Agopian3b1d2b62012-07-11 13:48:17 -0700487 mVisibleLayersSortedByZ = layers;
Mathias Agopian3b1d2b62012-07-11 13:48:17 -0700488}
489
Mathias Agopian13127d82013-03-05 17:47:11 -0800490const Vector< sp<Layer> >& DisplayDevice::getVisibleLayersSortedByZ() const {
Mathias Agopian3b1d2b62012-07-11 13:48:17 -0700491 return mVisibleLayersSortedByZ;
492}
493
Chia-I Wu83806892017-11-16 10:50:20 -0800494void DisplayDevice::setLayersNeedingFences(const Vector< sp<Layer> >& layers) {
495 mLayersNeedingFences = layers;
496}
497
498const Vector< sp<Layer> >& DisplayDevice::getLayersNeedingFences() const {
499 return mLayersNeedingFences;
500}
501
Mathias Agopian3b1d2b62012-07-11 13:48:17 -0700502// ----------------------------------------------------------------------------
Prashant Malani2c9b11f2014-05-25 01:36:31 -0700503void DisplayDevice::setPowerMode(int mode) {
504 mPowerMode = mode;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700505 getCompositionDisplay()->setCompositionEnabled(mPowerMode != HWC_POWER_MODE_OFF);
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700506}
507
Prashant Malani2c9b11f2014-05-25 01:36:31 -0700508int DisplayDevice::getPowerMode() const {
509 return mPowerMode;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700510}
511
Dominik Laskowskieecd6592018-05-29 10:25:41 -0700512bool DisplayDevice::isPoweredOn() const {
513 return mPowerMode != HWC_POWER_MODE_OFF;
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700514}
515
516// ----------------------------------------------------------------------------
Michael Lentine6c9e34a2014-07-14 13:48:55 -0700517void DisplayDevice::setActiveConfig(int mode) {
518 mActiveConfig = mode;
519}
520
521int DisplayDevice::getActiveConfig() const {
522 return mActiveConfig;
523}
524
525// ----------------------------------------------------------------------------
Yiwei Zhang7c64f172018-03-07 14:52:28 -0800526
Peiyong Lin34beb7a2018-03-28 11:57:12 -0700527void DisplayDevice::setCompositionDataSpace(ui::Dataspace dataspace) {
Courtney Goeltzenleuchter79d27242017-07-13 17:54:01 -0600528 ANativeWindow* const window = mNativeWindow.get();
Peiyong Lin34beb7a2018-03-28 11:57:12 -0700529 native_window_set_buffers_data_space(window, static_cast<android_dataspace>(dataspace));
Courtney Goeltzenleuchter79d27242017-07-13 17:54:01 -0600530}
Michael Wright28f24d02016-07-12 13:30:53 -0700531
Peiyong Lindd9b2ae2018-03-01 16:22:45 -0800532ui::Dataspace DisplayDevice::getCompositionDataSpace() const {
Lloyd Pique32cbe282018-10-19 13:09:22 -0700533 return mCompositionDisplay->getState().dataspace;
Peiyong Lindd9b2ae2018-03-01 16:22:45 -0800534}
535
Michael Wright28f24d02016-07-12 13:30:53 -0700536// ----------------------------------------------------------------------------
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700537
Mathias Agopian28947d72012-08-08 18:51:15 -0700538void DisplayDevice::setLayerStack(uint32_t stack) {
Lloyd Pique32cbe282018-10-19 13:09:22 -0700539 mCompositionDisplay->setLayerStackFilter(!isPrimary(), stack);
Mathias Agopian28947d72012-08-08 18:51:15 -0700540}
541
542// ----------------------------------------------------------------------------
543
Lloyd Pique32cbe282018-10-19 13:09:22 -0700544uint32_t DisplayDevice::displayStateOrientationToTransformOrientation(int orientation) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700545 switch (orientation) {
Mathias Agopian3165cc22012-08-08 19:42:09 -0700546 case DisplayState::eOrientationDefault:
Lloyd Pique32cbe282018-10-19 13:09:22 -0700547 return ui::Transform::ROT_0;
Mathias Agopian3165cc22012-08-08 19:42:09 -0700548 case DisplayState::eOrientation90:
Lloyd Pique32cbe282018-10-19 13:09:22 -0700549 return ui::Transform::ROT_90;
Mathias Agopian3165cc22012-08-08 19:42:09 -0700550 case DisplayState::eOrientation180:
Lloyd Pique32cbe282018-10-19 13:09:22 -0700551 return ui::Transform::ROT_180;
Mathias Agopian3165cc22012-08-08 19:42:09 -0700552 case DisplayState::eOrientation270:
Lloyd Pique32cbe282018-10-19 13:09:22 -0700553 return ui::Transform::ROT_270;
Mathias Agopian1b031492012-06-20 17:51:20 -0700554 default:
Lloyd Pique32cbe282018-10-19 13:09:22 -0700555 return ui::Transform::ROT_INVALID;
556 }
557}
558
559status_t DisplayDevice::orientationToTransfrom(int orientation, int w, int h, ui::Transform* tr) {
560 uint32_t flags = displayStateOrientationToTransformOrientation(orientation);
561 if (flags == ui::Transform::ROT_INVALID) {
Mathias Agopian1b031492012-06-20 17:51:20 -0700562 return BAD_VALUE;
563 }
564 tr->set(flags, w, h);
565 return NO_ERROR;
566}
567
Michael Lentine47e45402014-07-18 15:34:25 -0700568void DisplayDevice::setDisplaySize(const int newWidth, const int newHeight) {
Michael Lentine47e45402014-07-18 15:34:25 -0700569 mDisplaySurface->resizeBuffers(newWidth, newHeight);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700570 mCompositionDisplay->setBounds(Rect(newWidth, newHeight));
Michael Lentine47e45402014-07-18 15:34:25 -0700571}
572
Mathias Agopian00e8c7a2012-09-04 19:30:46 -0700573void DisplayDevice::setProjection(int orientation,
Mathias Agopianf5f714a2013-02-26 16:54:05 -0800574 const Rect& newViewport, const Rect& newFrame) {
575 Rect viewport(newViewport);
576 Rect frame(newFrame);
577
Lloyd Pique32cbe282018-10-19 13:09:22 -0700578 mOrientation = orientation;
579
580 const Rect& displayBounds = getCompositionDisplay()->getState().bounds;
581 const int w = displayBounds.width();
582 const int h = displayBounds.height();
Mathias Agopianf5f714a2013-02-26 16:54:05 -0800583
Peiyong Linefefaac2018-08-17 12:27:51 -0700584 ui::Transform R;
Mathias Agopianf5f714a2013-02-26 16:54:05 -0800585 DisplayDevice::orientationToTransfrom(orientation, w, h, &R);
586
587 if (!frame.isValid()) {
588 // the destination frame can be invalid if it has never been set,
589 // in that case we assume the whole display frame.
590 frame = Rect(w, h);
591 }
592
593 if (viewport.isEmpty()) {
594 // viewport can be invalid if it has never been set, in that case
595 // we assume the whole display size.
596 // it's also invalid to have an empty viewport, so we handle that
597 // case in the same way.
598 viewport = Rect(w, h);
Peiyong Linefefaac2018-08-17 12:27:51 -0700599 if (R.getOrientation() & ui::Transform::ROT_90) {
Mathias Agopianf5f714a2013-02-26 16:54:05 -0800600 // viewport is always specified in the logical orientation
601 // of the display (ie: post-rotation).
Peiyong Lin3db42342018-08-16 09:15:59 -0700602 std::swap(viewport.right, viewport.bottom);
Mathias Agopianf5f714a2013-02-26 16:54:05 -0800603 }
604 }
605
Peiyong Linefefaac2018-08-17 12:27:51 -0700606 ui::Transform TL, TP, S;
Mathias Agopianf5f714a2013-02-26 16:54:05 -0800607 float src_width = viewport.width();
608 float src_height = viewport.height();
609 float dst_width = frame.width();
610 float dst_height = frame.height();
611 if (src_width != dst_width || src_height != dst_height) {
612 float sx = dst_width / src_width;
613 float sy = dst_height / src_height;
614 S.set(sx, 0, 0, sy);
615 }
616
617 float src_x = viewport.left;
618 float src_y = viewport.top;
619 float dst_x = frame.left;
620 float dst_y = frame.top;
621 TL.set(-src_x, -src_y);
622 TP.set(dst_x, dst_y);
623
Lloyd Pique32cbe282018-10-19 13:09:22 -0700624 // need to take care of primary display rotation for globalTransform
Iris Chang7501ed62018-04-30 14:45:42 +0800625 // for case if the panel is not installed aligned with device orientation
Dominik Laskowski075d3172018-05-24 15:50:06 -0700626 if (isPrimary()) {
Iris Chang7501ed62018-04-30 14:45:42 +0800627 DisplayDevice::orientationToTransfrom(
Chia-I Wua02871c2018-08-27 14:38:23 -0700628 (orientation + mDisplayInstallOrientation) % (DisplayState::eOrientation270 + 1),
Iris Chang7501ed62018-04-30 14:45:42 +0800629 w, h, &R);
630 }
631
Mathias Agopianf5f714a2013-02-26 16:54:05 -0800632 // The viewport and frame are both in the logical orientation.
633 // Apply the logical translation, scale to physical size, apply the
634 // physical translation and finally rotate to the physical orientation.
Lloyd Pique32cbe282018-10-19 13:09:22 -0700635 ui::Transform globalTransform = R * TP * S * TL;
Mathias Agopianf5f714a2013-02-26 16:54:05 -0800636
Lloyd Pique32cbe282018-10-19 13:09:22 -0700637 const uint8_t type = globalTransform.getType();
638 const bool needsFiltering =
639 (!globalTransform.preserveRects() || (type >= ui::Transform::SCALE));
Mathias Agopianf5f714a2013-02-26 16:54:05 -0800640
Lloyd Pique32cbe282018-10-19 13:09:22 -0700641 Rect scissor = globalTransform.transform(viewport);
642 if (scissor.isEmpty()) {
643 scissor = displayBounds;
Mathias Agopianf5f714a2013-02-26 16:54:05 -0800644 }
645
Dominik Laskowski281644e2018-04-19 15:47:35 -0700646 if (isPrimary()) {
Lloyd Pique32cbe282018-10-19 13:09:22 -0700647 sPrimaryDisplayOrientation = displayStateOrientationToTransformOrientation(orientation);
Pablo Ceballos021623b2016-04-15 17:31:51 -0700648 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700649
650 getCompositionDisplay()->setProjection(globalTransform,
651 displayStateOrientationToTransformOrientation(
652 orientation),
653 frame, viewport, scissor, needsFiltering);
Mathias Agopian1b031492012-06-20 17:51:20 -0700654}
Mathias Agopian1d12d8a2012-09-18 01:38:00 -0700655
Pablo Ceballos021623b2016-04-15 17:31:51 -0700656uint32_t DisplayDevice::getPrimaryDisplayOrientationTransform() {
657 return sPrimaryDisplayOrientation;
658}
659
Dominik Laskowski9b17b2c22018-11-01 14:49:03 -0700660std::string DisplayDevice::getDebugName() const {
Lloyd Pique45a165a2018-10-19 11:54:47 -0700661 const auto id = getId() ? to_string(*getId()) + ", " : std::string();
Dominik Laskowski9b17b2c22018-11-01 14:49:03 -0700662 return base::StringPrintf("DisplayDevice{%s%s%s\"%s\"}", id.c_str(),
663 isPrimary() ? "primary, " : "", isVirtual() ? "virtual, " : "",
664 mDisplayName.c_str());
665}
666
Yiwei Zhang5434a782018-12-05 18:06:32 -0800667void DisplayDevice::dump(std::string& result) const {
Courtney Goeltzenleuchter152279d2017-08-14 18:18:30 -0600668 ANativeWindow* const window = mNativeWindow.get();
Yiwei Zhang5434a782018-12-05 18:06:32 -0800669 StringAppendF(&result, "+ %s\n", getDebugName().c_str());
Lloyd Pique32cbe282018-10-19 13:09:22 -0700670
671 result.append(" ");
672 StringAppendF(&result, "ANativeWindow=%p (format %d), ", window,
673 ANativeWindow_getFormat(window));
674 StringAppendF(&result, "flips=%u, ", getPageFlipCount());
675 StringAppendF(&result, "powerMode=%d, ", mPowerMode);
676 StringAppendF(&result, "activeConfig=%d, ", mActiveConfig);
677 StringAppendF(&result, "numLayers=%zu\n", mVisibleLayersSortedByZ.size());
678 getCompositionDisplay()->dump(result);
Courtney Goeltzenleuchter152279d2017-08-14 18:18:30 -0600679 auto const surface = static_cast<Surface*>(window);
Peiyong Lin34beb7a2018-03-28 11:57:12 -0700680 ui::Dataspace dataspace = surface->getBuffersDataSpace();
Lloyd Pique32cbe282018-10-19 13:09:22 -0700681 StringAppendF(&result, " wideColorGamut=%d, hdr10plus =%d, hdr10=%d, dataspace: %s (%d)\n",
Valerie Haue9e843a2018-12-18 13:39:23 -0800682 mHasWideColorGamut, mHasHdr10Plus, mHasHdr10,
Yiwei Zhang5434a782018-12-05 18:06:32 -0800683 dataspaceDetails(static_cast<android_dataspace>(dataspace)).c_str(), dataspace);
Mathias Agopian1d12d8a2012-09-18 01:38:00 -0700684
Jesse Hall99c7dbb2013-03-14 14:29:29 -0700685 String8 surfaceDump;
Dan Stozaf10c46e2014-11-11 10:32:31 -0800686 mDisplaySurface->dumpAsString(surfaceDump);
Yiwei Zhang5434a782018-12-05 18:06:32 -0800687 result.append(surfaceDump.string(), surfaceDump.size());
Mathias Agopian1d12d8a2012-09-18 01:38:00 -0700688}
Irvelffc9efc2016-07-27 15:16:37 -0700689
Chia-I Wube02ec02018-05-18 10:59:36 -0700690// Map dataspace/intent to the best matched dataspace/colorMode/renderIntent
691// supported by HWC.
692void DisplayDevice::addColorMode(
693 const std::unordered_map<ColorMode, std::vector<RenderIntent>>& hwcColorModes,
694 const ColorMode mode, const RenderIntent intent) {
695 // find the best color mode
696 const ColorMode hwcColorMode = getHwcColorMode(hwcColorModes, mode);
697
698 // find the best render intent
699 auto iter = hwcColorModes.find(hwcColorMode);
700 const auto& hwcIntents =
701 iter != hwcColorModes.end() ? iter->second : std::vector<RenderIntent>();
702 const RenderIntent hwcIntent = getHwcRenderIntent(hwcIntents, intent);
703
704 const Dataspace dataspace = colorModeToDataspace(mode);
705 const Dataspace hwcDataspace = colorModeToDataspace(hwcColorMode);
706
Dominik Laskowski9b17b2c22018-11-01 14:49:03 -0700707 ALOGV("%s: map (%s, %s) to (%s, %s, %s)", getDebugName().c_str(),
Chia-I Wube02ec02018-05-18 10:59:36 -0700708 dataspaceDetails(static_cast<android_dataspace_t>(dataspace)).c_str(),
709 decodeRenderIntent(intent).c_str(),
710 dataspaceDetails(static_cast<android_dataspace_t>(hwcDataspace)).c_str(),
711 decodeColorMode(hwcColorMode).c_str(), decodeRenderIntent(hwcIntent).c_str());
712
713 mColorModes[getColorModeKey(dataspace, intent)] = {hwcDataspace, hwcColorMode, hwcIntent};
714}
715
716void DisplayDevice::populateColorModes(
717 const std::unordered_map<ColorMode, std::vector<RenderIntent>>& hwcColorModes) {
718 if (!hasWideColorGamut()) {
719 return;
720 }
721
Chia-I Wu0d711262018-05-21 15:19:35 -0700722 // collect all known SDR render intents
723 std::unordered_set<RenderIntent> sdrRenderIntents(sSdrRenderIntents.begin(),
724 sSdrRenderIntents.end());
725 auto iter = hwcColorModes.find(ColorMode::SRGB);
726 if (iter != hwcColorModes.end()) {
727 for (auto intent : iter->second) {
728 sdrRenderIntents.insert(intent);
729 }
730 }
731
Chia-I Wuc4b08bd2018-05-29 12:57:23 -0700732 // add all known SDR combinations
Chia-I Wu0d711262018-05-21 15:19:35 -0700733 for (auto intent : sdrRenderIntents) {
Chia-I Wube02ec02018-05-18 10:59:36 -0700734 for (auto mode : sSdrColorModes) {
735 addColorMode(hwcColorModes, mode, intent);
Peiyong Lin136fbbc2018-04-17 15:09:44 -0700736 }
737 }
Chia-I Wube02ec02018-05-18 10:59:36 -0700738
Chia-I Wuc4b08bd2018-05-29 12:57:23 -0700739 // collect all known HDR render intents
740 std::unordered_set<RenderIntent> hdrRenderIntents(sHdrRenderIntents.begin(),
741 sHdrRenderIntents.end());
742 iter = hwcColorModes.find(ColorMode::BT2100_PQ);
743 if (iter != hwcColorModes.end()) {
744 for (auto intent : iter->second) {
745 hdrRenderIntents.insert(intent);
746 }
747 }
748
749 // add all known HDR combinations
Chia-I Wube02ec02018-05-18 10:59:36 -0700750 for (auto intent : sHdrRenderIntents) {
751 for (auto mode : sHdrColorModes) {
752 addColorMode(hwcColorModes, mode, intent);
753 }
754 }
755}
756
757bool DisplayDevice::hasRenderIntent(RenderIntent intent) const {
758 // assume a render intent is supported when SRGB supports it; we should
759 // get rid of that assumption.
Peiyong Lin14724e62018-12-05 07:27:30 -0800760 auto iter = mColorModes.find(getColorModeKey(Dataspace::V0_SRGB, intent));
Chia-I Wube02ec02018-05-18 10:59:36 -0700761 return iter != mColorModes.end() && iter->second.renderIntent == intent;
762}
763
Peiyong Lindfde5112018-06-05 10:58:41 -0700764bool DisplayDevice::hasLegacyHdrSupport(Dataspace dataspace) const {
Chia-I Wube02ec02018-05-18 10:59:36 -0700765 if ((dataspace == Dataspace::BT2020_PQ && hasHDR10Support()) ||
766 (dataspace == Dataspace::BT2020_HLG && hasHLGSupport())) {
767 auto iter =
768 mColorModes.find(getColorModeKey(dataspace, RenderIntent::TONE_MAP_COLORIMETRIC));
Peiyong Lindfde5112018-06-05 10:58:41 -0700769 return iter == mColorModes.end() || iter->second.dataspace != dataspace;
Chia-I Wube02ec02018-05-18 10:59:36 -0700770 }
771
772 return false;
773}
774
775void DisplayDevice::getBestColorMode(Dataspace dataspace, RenderIntent intent,
776 Dataspace* outDataspace, ColorMode* outMode,
777 RenderIntent* outIntent) const {
778 auto iter = mColorModes.find(getColorModeKey(dataspace, intent));
779 if (iter != mColorModes.end()) {
780 *outDataspace = iter->second.dataspace;
781 *outMode = iter->second.colorMode;
782 *outIntent = iter->second.renderIntent;
783 } else {
Chia-I Wu6333af52018-10-16 13:46:36 -0700784 // this is unexpected on a WCG display
785 if (hasWideColorGamut()) {
786 ALOGE("map unknown (%s)/(%s) to default color mode",
787 dataspaceDetails(static_cast<android_dataspace_t>(dataspace)).c_str(),
788 decodeRenderIntent(intent).c_str());
789 }
Chia-I Wube02ec02018-05-18 10:59:36 -0700790
791 *outDataspace = Dataspace::UNKNOWN;
792 *outMode = ColorMode::NATIVE;
793 *outIntent = RenderIntent::COLORIMETRIC;
794 }
Peiyong Lin136fbbc2018-04-17 15:09:44 -0700795}
796
Lloyd Pique45a165a2018-10-19 11:54:47 -0700797// ----------------------------------------------------------------------------
798
799const std::optional<DisplayId>& DisplayDevice::getId() const {
800 return mCompositionDisplay->getId();
801}
802
803bool DisplayDevice::isSecure() const {
804 return mCompositionDisplay->isSecure();
805}
806
Lloyd Pique32cbe282018-10-19 13:09:22 -0700807const Rect& DisplayDevice::getBounds() const {
808 return mCompositionDisplay->getState().bounds;
809}
810
811const Region& DisplayDevice::getUndefinedRegion() const {
812 return mCompositionDisplay->getState().undefinedRegion;
813}
814
815bool DisplayDevice::needsFiltering() const {
816 return mCompositionDisplay->getState().needsFiltering;
817}
818
819uint32_t DisplayDevice::getLayerStack() const {
820 return mCompositionDisplay->getState().singleLayerStackId;
821}
822
823const ui::Transform& DisplayDevice::getTransform() const {
824 return mCompositionDisplay->getState().transform;
825}
826
827const Rect& DisplayDevice::getViewport() const {
828 return mCompositionDisplay->getState().viewport;
829}
830
831const Rect& DisplayDevice::getFrame() const {
832 return mCompositionDisplay->getState().frame;
833}
834
835const Rect& DisplayDevice::getScissor() const {
836 return mCompositionDisplay->getState().scissor;
837}
838
Dominik Laskowski663bd282018-04-19 15:26:54 -0700839std::atomic<int32_t> DisplayDeviceState::sNextSequenceId(1);
Peiyong Linfd997e02018-03-28 15:29:00 -0700840
841} // namespace android