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