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