• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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