1 /*
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
17 // #define LOG_NDEBUG 0
18 #undef LOG_TAG
19 #define LOG_TAG "DisplayDevice"
20
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <math.h>
25
26 #include <cutils/properties.h>
27
28 #include <utils/RefBase.h>
29 #include <utils/Log.h>
30
31 #include <ui/DisplayInfo.h>
32 #include <ui/PixelFormat.h>
33
34 #include <gui/Surface.h>
35
36 #include <hardware/gralloc.h>
37
38 #include "DisplayHardware/DisplaySurface.h"
39 #include "DisplayHardware/HWComposer.h"
40 #ifdef USE_HWC2
41 #include "DisplayHardware/HWC2.h"
42 #endif
43 #include "RenderEngine/RenderEngine.h"
44
45 #include "clz.h"
46 #include "DisplayDevice.h"
47 #include "SurfaceFlinger.h"
48 #include "Layer.h"
49
50 #include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
51 #include <configstore/Utils.h>
52
53 // ----------------------------------------------------------------------------
54 using namespace android;
55 // ----------------------------------------------------------------------------
56
57 #ifdef EGL_ANDROID_swap_rectangle
58 static constexpr bool kEGLAndroidSwapRectangle = true;
59 #else
60 static constexpr bool kEGLAndroidSwapRectangle = false;
61 #endif
62
63 // retrieve triple buffer setting from configstore
64 using namespace android::hardware::configstore;
65 using namespace android::hardware::configstore::V1_0;
66
67 static bool useTripleFramebuffer = getInt64< ISurfaceFlingerConfigs,
68 &ISurfaceFlingerConfigs::maxFrameBufferAcquiredBuffers>(2) == 3;
69
70 #if !defined(EGL_EGLEXT_PROTOTYPES) || !defined(EGL_ANDROID_swap_rectangle)
71 // Dummy implementation in case it is missing.
eglSetSwapRectangleANDROID(EGLDisplay,EGLSurface,EGLint,EGLint,EGLint,EGLint)72 inline void eglSetSwapRectangleANDROID (EGLDisplay, EGLSurface, EGLint, EGLint, EGLint, EGLint) {
73 }
74 #endif
75
76 /*
77 * Initialize the display to the specified values.
78 *
79 */
80
81 uint32_t DisplayDevice::sPrimaryDisplayOrientation = 0;
82
83 // clang-format off
DisplayDevice(const sp<SurfaceFlinger> & flinger,DisplayType type,int32_t hwcId,int format,bool isSecure,const wp<IBinder> & displayToken,const sp<DisplaySurface> & displaySurface,const sp<IGraphicBufferProducer> & producer,EGLConfig config,bool supportWideColor)84 DisplayDevice::DisplayDevice(
85 const sp<SurfaceFlinger>& flinger,
86 DisplayType type,
87 int32_t hwcId,
88 #ifndef USE_HWC2
89 int format,
90 #endif
91 bool isSecure,
92 const wp<IBinder>& displayToken,
93 const sp<DisplaySurface>& displaySurface,
94 const sp<IGraphicBufferProducer>& producer,
95 EGLConfig config,
96 bool supportWideColor)
97 : lastCompositionHadVisibleLayers(false),
98 mFlinger(flinger),
99 mType(type),
100 mHwcDisplayId(hwcId),
101 mDisplayToken(displayToken),
102 mDisplaySurface(displaySurface),
103 mDisplay(EGL_NO_DISPLAY),
104 mSurface(EGL_NO_SURFACE),
105 mDisplayWidth(),
106 mDisplayHeight(),
107 #ifndef USE_HWC2
108 mFormat(),
109 #endif
110 mFlags(),
111 mPageFlipCount(),
112 mIsSecure(isSecure),
113 mLayerStack(NO_LAYER_STACK),
114 mOrientation(),
115 mPowerMode(HWC_POWER_MODE_OFF),
116 mActiveConfig(0)
117 {
118 // clang-format on
119 Surface* surface;
120 mNativeWindow = surface = new Surface(producer, false);
121 ANativeWindow* const window = mNativeWindow.get();
122
123 #ifdef USE_HWC2
124 mActiveColorMode = HAL_COLOR_MODE_NATIVE;
125 mDisplayHasWideColor = supportWideColor;
126 #else
127 (void) supportWideColor;
128 #endif
129 /*
130 * Create our display's surface
131 */
132
133 EGLSurface eglSurface;
134 EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
135 if (config == EGL_NO_CONFIG) {
136 #ifdef USE_HWC2
137 config = RenderEngine::chooseEglConfig(display, PIXEL_FORMAT_RGBA_8888,
138 /*logConfig*/ false);
139 #else
140 config = RenderEngine::chooseEglConfig(display, format,
141 /*logConfig*/ false);
142 #endif
143 }
144 eglSurface = eglCreateWindowSurface(display, config, window, NULL);
145 eglQuerySurface(display, eglSurface, EGL_WIDTH, &mDisplayWidth);
146 eglQuerySurface(display, eglSurface, EGL_HEIGHT, &mDisplayHeight);
147
148 // Make sure that composition can never be stalled by a virtual display
149 // consumer that isn't processing buffers fast enough. We have to do this
150 // in two places:
151 // * Here, in case the display is composed entirely by HWC.
152 // * In makeCurrent(), using eglSwapInterval. Some EGL drivers set the
153 // window's swap interval in eglMakeCurrent, so they'll override the
154 // interval we set here.
155 if (mType >= DisplayDevice::DISPLAY_VIRTUAL)
156 window->setSwapInterval(window, 0);
157
158 mConfig = config;
159 mDisplay = display;
160 mSurface = eglSurface;
161 #ifndef USE_HWC2
162 mFormat = format;
163 #endif
164 mPageFlipCount = 0;
165 mViewport.makeInvalid();
166 mFrame.makeInvalid();
167
168 // virtual displays are always considered enabled
169 mPowerMode = (mType >= DisplayDevice::DISPLAY_VIRTUAL) ?
170 HWC_POWER_MODE_NORMAL : HWC_POWER_MODE_OFF;
171
172 // Name the display. The name will be replaced shortly if the display
173 // was created with createDisplay().
174 switch (mType) {
175 case DISPLAY_PRIMARY:
176 mDisplayName = "Built-in Screen";
177 break;
178 case DISPLAY_EXTERNAL:
179 mDisplayName = "HDMI Screen";
180 break;
181 default:
182 mDisplayName = "Virtual Screen"; // e.g. Overlay #n
183 break;
184 }
185
186 // initialize the display orientation transform.
187 setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);
188
189 if (useTripleFramebuffer) {
190 surface->allocateBuffers();
191 }
192 }
193
~DisplayDevice()194 DisplayDevice::~DisplayDevice() {
195 if (mSurface != EGL_NO_SURFACE) {
196 eglDestroySurface(mDisplay, mSurface);
197 mSurface = EGL_NO_SURFACE;
198 }
199 }
200
disconnect(HWComposer & hwc)201 void DisplayDevice::disconnect(HWComposer& hwc) {
202 if (mHwcDisplayId >= 0) {
203 hwc.disconnectDisplay(mHwcDisplayId);
204 #ifndef USE_HWC2
205 if (mHwcDisplayId >= DISPLAY_VIRTUAL)
206 hwc.freeDisplayId(mHwcDisplayId);
207 #endif
208 mHwcDisplayId = -1;
209 }
210 }
211
isValid() const212 bool DisplayDevice::isValid() const {
213 return mFlinger != NULL;
214 }
215
getWidth() const216 int DisplayDevice::getWidth() const {
217 return mDisplayWidth;
218 }
219
getHeight() const220 int DisplayDevice::getHeight() const {
221 return mDisplayHeight;
222 }
223
224 #ifndef USE_HWC2
getFormat() const225 PixelFormat DisplayDevice::getFormat() const {
226 return mFormat;
227 }
228 #endif
229
getEGLSurface() const230 EGLSurface DisplayDevice::getEGLSurface() const {
231 return mSurface;
232 }
233
setDisplayName(const String8 & displayName)234 void DisplayDevice::setDisplayName(const String8& displayName) {
235 if (!displayName.isEmpty()) {
236 // never override the name with an empty name
237 mDisplayName = displayName;
238 }
239 }
240
getPageFlipCount() const241 uint32_t DisplayDevice::getPageFlipCount() const {
242 return mPageFlipCount;
243 }
244
245 #ifndef USE_HWC2
compositionComplete() const246 status_t DisplayDevice::compositionComplete() const {
247 return mDisplaySurface->compositionComplete();
248 }
249 #endif
250
flip(const Region & dirty) const251 void DisplayDevice::flip(const Region& dirty) const
252 {
253 mFlinger->getRenderEngine().checkErrors();
254
255 if (kEGLAndroidSwapRectangle) {
256 if (mFlags & SWAP_RECTANGLE) {
257 const Region newDirty(dirty.intersect(bounds()));
258 const Rect b(newDirty.getBounds());
259 eglSetSwapRectangleANDROID(mDisplay, mSurface,
260 b.left, b.top, b.width(), b.height());
261 }
262 }
263
264 mPageFlipCount++;
265 }
266
beginFrame(bool mustRecompose) const267 status_t DisplayDevice::beginFrame(bool mustRecompose) const {
268 return mDisplaySurface->beginFrame(mustRecompose);
269 }
270
271 #ifdef USE_HWC2
prepareFrame(HWComposer & hwc)272 status_t DisplayDevice::prepareFrame(HWComposer& hwc) {
273 status_t error = hwc.prepare(*this);
274 if (error != NO_ERROR) {
275 return error;
276 }
277
278 DisplaySurface::CompositionType compositionType;
279 bool hasClient = hwc.hasClientComposition(mHwcDisplayId);
280 bool hasDevice = hwc.hasDeviceComposition(mHwcDisplayId);
281 if (hasClient && hasDevice) {
282 compositionType = DisplaySurface::COMPOSITION_MIXED;
283 } else if (hasClient) {
284 compositionType = DisplaySurface::COMPOSITION_GLES;
285 } else if (hasDevice) {
286 compositionType = DisplaySurface::COMPOSITION_HWC;
287 } else {
288 // Nothing to do -- when turning the screen off we get a frame like
289 // this. Call it a HWC frame since we won't be doing any GLES work but
290 // will do a prepare/set cycle.
291 compositionType = DisplaySurface::COMPOSITION_HWC;
292 }
293 return mDisplaySurface->prepareFrame(compositionType);
294 }
295 #else
prepareFrame(const HWComposer & hwc) const296 status_t DisplayDevice::prepareFrame(const HWComposer& hwc) const {
297 DisplaySurface::CompositionType compositionType;
298 bool haveGles = hwc.hasGlesComposition(mHwcDisplayId);
299 bool haveHwc = hwc.hasHwcComposition(mHwcDisplayId);
300 if (haveGles && haveHwc) {
301 compositionType = DisplaySurface::COMPOSITION_MIXED;
302 } else if (haveGles) {
303 compositionType = DisplaySurface::COMPOSITION_GLES;
304 } else if (haveHwc) {
305 compositionType = DisplaySurface::COMPOSITION_HWC;
306 } else {
307 // Nothing to do -- when turning the screen off we get a frame like
308 // this. Call it a HWC frame since we won't be doing any GLES work but
309 // will do a prepare/set cycle.
310 compositionType = DisplaySurface::COMPOSITION_HWC;
311 }
312 return mDisplaySurface->prepareFrame(compositionType);
313 }
314 #endif
315
swapBuffers(HWComposer & hwc) const316 void DisplayDevice::swapBuffers(HWComposer& hwc) const {
317 #ifdef USE_HWC2
318 if (hwc.hasClientComposition(mHwcDisplayId)) {
319 #else
320 // We need to call eglSwapBuffers() if:
321 // (1) we don't have a hardware composer, or
322 // (2) we did GLES composition this frame, and either
323 // (a) we have framebuffer target support (not present on legacy
324 // devices, where HWComposer::commit() handles things); or
325 // (b) this is a virtual display
326 if (hwc.initCheck() != NO_ERROR ||
327 (hwc.hasGlesComposition(mHwcDisplayId) &&
328 (hwc.supportsFramebufferTarget() || mType >= DISPLAY_VIRTUAL))) {
329 #endif
330 EGLBoolean success = eglSwapBuffers(mDisplay, mSurface);
331 if (!success) {
332 EGLint error = eglGetError();
333 if (error == EGL_CONTEXT_LOST ||
334 mType == DisplayDevice::DISPLAY_PRIMARY) {
335 LOG_ALWAYS_FATAL("eglSwapBuffers(%p, %p) failed with 0x%08x",
336 mDisplay, mSurface, error);
337 } else {
338 ALOGE("eglSwapBuffers(%p, %p) failed with 0x%08x",
339 mDisplay, mSurface, error);
340 }
341 }
342 }
343
344 status_t result = mDisplaySurface->advanceFrame();
345 if (result != NO_ERROR) {
346 ALOGE("[%s] failed pushing new frame to HWC: %d",
347 mDisplayName.string(), result);
348 }
349 }
350
351 #ifdef USE_HWC2
352 void DisplayDevice::onSwapBuffersCompleted() const {
353 mDisplaySurface->onFrameCommitted();
354 }
355 #else
356 void DisplayDevice::onSwapBuffersCompleted(HWComposer& hwc) const {
357 if (hwc.initCheck() == NO_ERROR) {
358 mDisplaySurface->onFrameCommitted();
359 }
360 }
361 #endif
362
363 uint32_t DisplayDevice::getFlags() const
364 {
365 return mFlags;
366 }
367
368 EGLBoolean DisplayDevice::makeCurrent(EGLDisplay dpy, EGLContext ctx) const {
369 EGLBoolean result = EGL_TRUE;
370 EGLSurface sur = eglGetCurrentSurface(EGL_DRAW);
371 if (sur != mSurface) {
372 result = eglMakeCurrent(dpy, mSurface, mSurface, ctx);
373 if (result == EGL_TRUE) {
374 if (mType >= DisplayDevice::DISPLAY_VIRTUAL)
375 eglSwapInterval(dpy, 0);
376 }
377 }
378 setViewportAndProjection();
379 return result;
380 }
381
382 void DisplayDevice::setViewportAndProjection() const {
383 size_t w = mDisplayWidth;
384 size_t h = mDisplayHeight;
385 Rect sourceCrop(0, 0, w, h);
386 mFlinger->getRenderEngine().setViewportAndProjection(w, h, sourceCrop, h,
387 false, Transform::ROT_0);
388 }
389
390 const sp<Fence>& DisplayDevice::getClientTargetAcquireFence() const {
391 return mDisplaySurface->getClientTargetAcquireFence();
392 }
393
394 // ----------------------------------------------------------------------------
395
396 void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers) {
397 mVisibleLayersSortedByZ = layers;
398 }
399
400 const Vector< sp<Layer> >& DisplayDevice::getVisibleLayersSortedByZ() const {
401 return mVisibleLayersSortedByZ;
402 }
403
404 Region DisplayDevice::getDirtyRegion(bool repaintEverything) const {
405 Region dirty;
406 if (repaintEverything) {
407 dirty.set(getBounds());
408 } else {
409 const Transform& planeTransform(mGlobalTransform);
410 dirty = planeTransform.transform(this->dirtyRegion);
411 dirty.andSelf(getBounds());
412 }
413 return dirty;
414 }
415
416 // ----------------------------------------------------------------------------
417 void DisplayDevice::setPowerMode(int mode) {
418 mPowerMode = mode;
419 }
420
421 int DisplayDevice::getPowerMode() const {
422 return mPowerMode;
423 }
424
425 bool DisplayDevice::isDisplayOn() const {
426 return (mPowerMode != HWC_POWER_MODE_OFF);
427 }
428
429 // ----------------------------------------------------------------------------
430 void DisplayDevice::setActiveConfig(int mode) {
431 mActiveConfig = mode;
432 }
433
434 int DisplayDevice::getActiveConfig() const {
435 return mActiveConfig;
436 }
437
438 // ----------------------------------------------------------------------------
439 #ifdef USE_HWC2
440 void DisplayDevice::setActiveColorMode(android_color_mode_t mode) {
441 mActiveColorMode = mode;
442 }
443
444 android_color_mode_t DisplayDevice::getActiveColorMode() const {
445 return mActiveColorMode;
446 }
447
448 void DisplayDevice::setCompositionDataSpace(android_dataspace dataspace) {
449 ANativeWindow* const window = mNativeWindow.get();
450 native_window_set_buffers_data_space(window, dataspace);
451 }
452 #endif
453
454 // ----------------------------------------------------------------------------
455
456 void DisplayDevice::setLayerStack(uint32_t stack) {
457 mLayerStack = stack;
458 dirtyRegion.set(bounds());
459 }
460
461 // ----------------------------------------------------------------------------
462
463 uint32_t DisplayDevice::getOrientationTransform() const {
464 uint32_t transform = 0;
465 switch (mOrientation) {
466 case DisplayState::eOrientationDefault:
467 transform = Transform::ROT_0;
468 break;
469 case DisplayState::eOrientation90:
470 transform = Transform::ROT_90;
471 break;
472 case DisplayState::eOrientation180:
473 transform = Transform::ROT_180;
474 break;
475 case DisplayState::eOrientation270:
476 transform = Transform::ROT_270;
477 break;
478 }
479 return transform;
480 }
481
482 status_t DisplayDevice::orientationToTransfrom(
483 int orientation, int w, int h, Transform* tr)
484 {
485 uint32_t flags = 0;
486 switch (orientation) {
487 case DisplayState::eOrientationDefault:
488 flags = Transform::ROT_0;
489 break;
490 case DisplayState::eOrientation90:
491 flags = Transform::ROT_90;
492 break;
493 case DisplayState::eOrientation180:
494 flags = Transform::ROT_180;
495 break;
496 case DisplayState::eOrientation270:
497 flags = Transform::ROT_270;
498 break;
499 default:
500 return BAD_VALUE;
501 }
502 tr->set(flags, w, h);
503 return NO_ERROR;
504 }
505
506 void DisplayDevice::setDisplaySize(const int newWidth, const int newHeight) {
507 dirtyRegion.set(getBounds());
508
509 if (mSurface != EGL_NO_SURFACE) {
510 eglDestroySurface(mDisplay, mSurface);
511 mSurface = EGL_NO_SURFACE;
512 }
513
514 mDisplaySurface->resizeBuffers(newWidth, newHeight);
515
516 ANativeWindow* const window = mNativeWindow.get();
517 mSurface = eglCreateWindowSurface(mDisplay, mConfig, window, NULL);
518 eglQuerySurface(mDisplay, mSurface, EGL_WIDTH, &mDisplayWidth);
519 eglQuerySurface(mDisplay, mSurface, EGL_HEIGHT, &mDisplayHeight);
520
521 LOG_FATAL_IF(mDisplayWidth != newWidth,
522 "Unable to set new width to %d", newWidth);
523 LOG_FATAL_IF(mDisplayHeight != newHeight,
524 "Unable to set new height to %d", newHeight);
525 }
526
527 void DisplayDevice::setProjection(int orientation,
528 const Rect& newViewport, const Rect& newFrame) {
529 Rect viewport(newViewport);
530 Rect frame(newFrame);
531
532 const int w = mDisplayWidth;
533 const int h = mDisplayHeight;
534
535 Transform R;
536 DisplayDevice::orientationToTransfrom(orientation, w, h, &R);
537
538 if (!frame.isValid()) {
539 // the destination frame can be invalid if it has never been set,
540 // in that case we assume the whole display frame.
541 frame = Rect(w, h);
542 }
543
544 if (viewport.isEmpty()) {
545 // viewport can be invalid if it has never been set, in that case
546 // we assume the whole display size.
547 // it's also invalid to have an empty viewport, so we handle that
548 // case in the same way.
549 viewport = Rect(w, h);
550 if (R.getOrientation() & Transform::ROT_90) {
551 // viewport is always specified in the logical orientation
552 // of the display (ie: post-rotation).
553 swap(viewport.right, viewport.bottom);
554 }
555 }
556
557 dirtyRegion.set(getBounds());
558
559 Transform TL, TP, S;
560 float src_width = viewport.width();
561 float src_height = viewport.height();
562 float dst_width = frame.width();
563 float dst_height = frame.height();
564 if (src_width != dst_width || src_height != dst_height) {
565 float sx = dst_width / src_width;
566 float sy = dst_height / src_height;
567 S.set(sx, 0, 0, sy);
568 }
569
570 float src_x = viewport.left;
571 float src_y = viewport.top;
572 float dst_x = frame.left;
573 float dst_y = frame.top;
574 TL.set(-src_x, -src_y);
575 TP.set(dst_x, dst_y);
576
577 // The viewport and frame are both in the logical orientation.
578 // Apply the logical translation, scale to physical size, apply the
579 // physical translation and finally rotate to the physical orientation.
580 mGlobalTransform = R * TP * S * TL;
581
582 const uint8_t type = mGlobalTransform.getType();
583 mNeedsFiltering = (!mGlobalTransform.preserveRects() ||
584 (type >= Transform::SCALE));
585
586 mScissor = mGlobalTransform.transform(viewport);
587 if (mScissor.isEmpty()) {
588 mScissor = getBounds();
589 }
590
591 mOrientation = orientation;
592 if (mType == DisplayType::DISPLAY_PRIMARY) {
593 uint32_t transform = 0;
594 switch (mOrientation) {
595 case DisplayState::eOrientationDefault:
596 transform = Transform::ROT_0;
597 break;
598 case DisplayState::eOrientation90:
599 transform = Transform::ROT_90;
600 break;
601 case DisplayState::eOrientation180:
602 transform = Transform::ROT_180;
603 break;
604 case DisplayState::eOrientation270:
605 transform = Transform::ROT_270;
606 break;
607 }
608 sPrimaryDisplayOrientation = transform;
609 }
610 mViewport = viewport;
611 mFrame = frame;
612 }
613
614 uint32_t DisplayDevice::getPrimaryDisplayOrientationTransform() {
615 return sPrimaryDisplayOrientation;
616 }
617
618 void DisplayDevice::dump(String8& result) const {
619 const Transform& tr(mGlobalTransform);
620 EGLint redSize, greenSize, blueSize, alphaSize;
621 eglGetConfigAttrib(mDisplay, mConfig, EGL_RED_SIZE, &redSize);
622 eglGetConfigAttrib(mDisplay, mConfig, EGL_GREEN_SIZE, &greenSize);
623 eglGetConfigAttrib(mDisplay, mConfig, EGL_BLUE_SIZE, &blueSize);
624 eglGetConfigAttrib(mDisplay, mConfig, EGL_ALPHA_SIZE, &alphaSize);
625 result.appendFormat("+ DisplayDevice: %s\n", mDisplayName.string());
626 result.appendFormat(" type=%x, hwcId=%d, layerStack=%u, (%4dx%4d), ANativeWindow=%p "
627 "(%d:%d:%d:%d), orient=%2d (type=%08x), "
628 "flips=%u, isSecure=%d, powerMode=%d, activeConfig=%d, numLayers=%zu\n",
629 mType, mHwcDisplayId, mLayerStack, mDisplayWidth, mDisplayHeight,
630 mNativeWindow.get(), redSize, greenSize, blueSize, alphaSize, mOrientation,
631 tr.getType(), getPageFlipCount(), mIsSecure, mPowerMode, mActiveConfig,
632 mVisibleLayersSortedByZ.size());
633 result.appendFormat(" v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d],"
634 "transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n",
635 mViewport.left, mViewport.top, mViewport.right, mViewport.bottom,
636 mFrame.left, mFrame.top, mFrame.right, mFrame.bottom, mScissor.left,
637 mScissor.top, mScissor.right, mScissor.bottom, tr[0][0], tr[1][0], tr[2][0],
638 tr[0][1], tr[1][1], tr[2][1], tr[0][2], tr[1][2], tr[2][2]);
639
640 String8 surfaceDump;
641 mDisplaySurface->dumpAsString(surfaceDump);
642 result.append(surfaceDump);
643 }
644
645 std::atomic<int32_t> DisplayDeviceState::nextDisplayId(1);
646
647 DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type, bool isSecure)
648 : type(type),
649 layerStack(DisplayDevice::NO_LAYER_STACK),
650 orientation(0),
651 width(0),
652 height(0),
653 isSecure(isSecure)
654 {
655 viewport.makeInvalid();
656 frame.makeInvalid();
657 }
658