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 = static_cast<android_color_mode_t>(-1);
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 #else
139 config = RenderEngine::chooseEglConfig(display, format);
140 #endif
141 }
142 eglSurface = eglCreateWindowSurface(display, config, window, NULL);
143 eglQuerySurface(display, eglSurface, EGL_WIDTH, &mDisplayWidth);
144 eglQuerySurface(display, eglSurface, EGL_HEIGHT, &mDisplayHeight);
145
146 // Make sure that composition can never be stalled by a virtual display
147 // consumer that isn't processing buffers fast enough. We have to do this
148 // in two places:
149 // * Here, in case the display is composed entirely by HWC.
150 // * In makeCurrent(), using eglSwapInterval. Some EGL drivers set the
151 // window's swap interval in eglMakeCurrent, so they'll override the
152 // interval we set here.
153 if (mType >= DisplayDevice::DISPLAY_VIRTUAL)
154 window->setSwapInterval(window, 0);
155
156 mConfig = config;
157 mDisplay = display;
158 mSurface = eglSurface;
159 #ifndef USE_HWC2
160 mFormat = format;
161 #endif
162 mPageFlipCount = 0;
163 mViewport.makeInvalid();
164 mFrame.makeInvalid();
165
166 // virtual displays are always considered enabled
167 mPowerMode = (mType >= DisplayDevice::DISPLAY_VIRTUAL) ?
168 HWC_POWER_MODE_NORMAL : HWC_POWER_MODE_OFF;
169
170 // Name the display. The name will be replaced shortly if the display
171 // was created with createDisplay().
172 switch (mType) {
173 case DISPLAY_PRIMARY:
174 mDisplayName = "Built-in Screen";
175 break;
176 case DISPLAY_EXTERNAL:
177 mDisplayName = "HDMI Screen";
178 break;
179 default:
180 mDisplayName = "Virtual Screen"; // e.g. Overlay #n
181 break;
182 }
183
184 // initialize the display orientation transform.
185 setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);
186
187 if (useTripleFramebuffer) {
188 surface->allocateBuffers();
189 }
190 }
191
~DisplayDevice()192 DisplayDevice::~DisplayDevice() {
193 if (mSurface != EGL_NO_SURFACE) {
194 eglDestroySurface(mDisplay, mSurface);
195 mSurface = EGL_NO_SURFACE;
196 }
197 }
198
disconnect(HWComposer & hwc)199 void DisplayDevice::disconnect(HWComposer& hwc) {
200 if (mHwcDisplayId >= 0) {
201 hwc.disconnectDisplay(mHwcDisplayId);
202 #ifndef USE_HWC2
203 if (mHwcDisplayId >= DISPLAY_VIRTUAL)
204 hwc.freeDisplayId(mHwcDisplayId);
205 #endif
206 mHwcDisplayId = -1;
207 }
208 }
209
isValid() const210 bool DisplayDevice::isValid() const {
211 return mFlinger != NULL;
212 }
213
getWidth() const214 int DisplayDevice::getWidth() const {
215 return mDisplayWidth;
216 }
217
getHeight() const218 int DisplayDevice::getHeight() const {
219 return mDisplayHeight;
220 }
221
222 #ifndef USE_HWC2
getFormat() const223 PixelFormat DisplayDevice::getFormat() const {
224 return mFormat;
225 }
226 #endif
227
getEGLSurface() const228 EGLSurface DisplayDevice::getEGLSurface() const {
229 return mSurface;
230 }
231
setDisplayName(const String8 & displayName)232 void DisplayDevice::setDisplayName(const String8& displayName) {
233 if (!displayName.isEmpty()) {
234 // never override the name with an empty name
235 mDisplayName = displayName;
236 }
237 }
238
getPageFlipCount() const239 uint32_t DisplayDevice::getPageFlipCount() const {
240 return mPageFlipCount;
241 }
242
243 #ifndef USE_HWC2
compositionComplete() const244 status_t DisplayDevice::compositionComplete() const {
245 return mDisplaySurface->compositionComplete();
246 }
247 #endif
248
flip(const Region & dirty) const249 void DisplayDevice::flip(const Region& dirty) const
250 {
251 mFlinger->getRenderEngine().checkErrors();
252
253 if (kEGLAndroidSwapRectangle) {
254 if (mFlags & SWAP_RECTANGLE) {
255 const Region newDirty(dirty.intersect(bounds()));
256 const Rect b(newDirty.getBounds());
257 eglSetSwapRectangleANDROID(mDisplay, mSurface,
258 b.left, b.top, b.width(), b.height());
259 }
260 }
261
262 mPageFlipCount++;
263 }
264
beginFrame(bool mustRecompose) const265 status_t DisplayDevice::beginFrame(bool mustRecompose) const {
266 return mDisplaySurface->beginFrame(mustRecompose);
267 }
268
269 #ifdef USE_HWC2
prepareFrame(HWComposer & hwc)270 status_t DisplayDevice::prepareFrame(HWComposer& hwc) {
271 status_t error = hwc.prepare(*this);
272 if (error != NO_ERROR) {
273 return error;
274 }
275
276 DisplaySurface::CompositionType compositionType;
277 bool hasClient = hwc.hasClientComposition(mHwcDisplayId);
278 bool hasDevice = hwc.hasDeviceComposition(mHwcDisplayId);
279 if (hasClient && hasDevice) {
280 compositionType = DisplaySurface::COMPOSITION_MIXED;
281 } else if (hasClient) {
282 compositionType = DisplaySurface::COMPOSITION_GLES;
283 } else if (hasDevice) {
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 #else
prepareFrame(const HWComposer & hwc) const294 status_t DisplayDevice::prepareFrame(const HWComposer& hwc) const {
295 DisplaySurface::CompositionType compositionType;
296 bool haveGles = hwc.hasGlesComposition(mHwcDisplayId);
297 bool haveHwc = hwc.hasHwcComposition(mHwcDisplayId);
298 if (haveGles && haveHwc) {
299 compositionType = DisplaySurface::COMPOSITION_MIXED;
300 } else if (haveGles) {
301 compositionType = DisplaySurface::COMPOSITION_GLES;
302 } else if (haveHwc) {
303 compositionType = DisplaySurface::COMPOSITION_HWC;
304 } else {
305 // Nothing to do -- when turning the screen off we get a frame like
306 // this. Call it a HWC frame since we won't be doing any GLES work but
307 // will do a prepare/set cycle.
308 compositionType = DisplaySurface::COMPOSITION_HWC;
309 }
310 return mDisplaySurface->prepareFrame(compositionType);
311 }
312 #endif
313
swapBuffers(HWComposer & hwc) const314 void DisplayDevice::swapBuffers(HWComposer& hwc) const {
315 #ifdef USE_HWC2
316 if (hwc.hasClientComposition(mHwcDisplayId)) {
317 #else
318 // We need to call eglSwapBuffers() if:
319 // (1) we don't have a hardware composer, or
320 // (2) we did GLES composition this frame, and either
321 // (a) we have framebuffer target support (not present on legacy
322 // devices, where HWComposer::commit() handles things); or
323 // (b) this is a virtual display
324 if (hwc.initCheck() != NO_ERROR ||
325 (hwc.hasGlesComposition(mHwcDisplayId) &&
326 (hwc.supportsFramebufferTarget() || mType >= DISPLAY_VIRTUAL))) {
327 #endif
328 EGLBoolean success = eglSwapBuffers(mDisplay, mSurface);
329 if (!success) {
330 EGLint error = eglGetError();
331 if (error == EGL_CONTEXT_LOST ||
332 mType == DisplayDevice::DISPLAY_PRIMARY) {
333 LOG_ALWAYS_FATAL("eglSwapBuffers(%p, %p) failed with 0x%08x",
334 mDisplay, mSurface, error);
335 } else {
336 ALOGE("eglSwapBuffers(%p, %p) failed with 0x%08x",
337 mDisplay, mSurface, error);
338 }
339 }
340 }
341
342 status_t result = mDisplaySurface->advanceFrame();
343 if (result != NO_ERROR) {
344 ALOGE("[%s] failed pushing new frame to HWC: %d",
345 mDisplayName.string(), result);
346 }
347 }
348
349 #ifdef USE_HWC2
350 void DisplayDevice::onSwapBuffersCompleted() const {
351 mDisplaySurface->onFrameCommitted();
352 }
353 #else
354 void DisplayDevice::onSwapBuffersCompleted(HWComposer& hwc) const {
355 if (hwc.initCheck() == NO_ERROR) {
356 mDisplaySurface->onFrameCommitted();
357 }
358 }
359 #endif
360
361 uint32_t DisplayDevice::getFlags() const
362 {
363 return mFlags;
364 }
365
366 EGLBoolean DisplayDevice::makeCurrent(EGLDisplay dpy, EGLContext ctx) const {
367 EGLBoolean result = EGL_TRUE;
368 EGLSurface sur = eglGetCurrentSurface(EGL_DRAW);
369 if (sur != mSurface) {
370 result = eglMakeCurrent(dpy, mSurface, mSurface, ctx);
371 if (result == EGL_TRUE) {
372 if (mType >= DisplayDevice::DISPLAY_VIRTUAL)
373 eglSwapInterval(dpy, 0);
374 }
375 }
376 setViewportAndProjection();
377 return result;
378 }
379
380 void DisplayDevice::setViewportAndProjection() const {
381 size_t w = mDisplayWidth;
382 size_t h = mDisplayHeight;
383 Rect sourceCrop(0, 0, w, h);
384 mFlinger->getRenderEngine().setViewportAndProjection(w, h, sourceCrop, h,
385 false, Transform::ROT_0);
386 }
387
388 const sp<Fence>& DisplayDevice::getClientTargetAcquireFence() const {
389 return mDisplaySurface->getClientTargetAcquireFence();
390 }
391
392 // ----------------------------------------------------------------------------
393
394 void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers) {
395 mVisibleLayersSortedByZ = layers;
396 }
397
398 const Vector< sp<Layer> >& DisplayDevice::getVisibleLayersSortedByZ() const {
399 return mVisibleLayersSortedByZ;
400 }
401
402 Region DisplayDevice::getDirtyRegion(bool repaintEverything) const {
403 Region dirty;
404 if (repaintEverything) {
405 dirty.set(getBounds());
406 } else {
407 const Transform& planeTransform(mGlobalTransform);
408 dirty = planeTransform.transform(this->dirtyRegion);
409 dirty.andSelf(getBounds());
410 }
411 return dirty;
412 }
413
414 // ----------------------------------------------------------------------------
415 void DisplayDevice::setPowerMode(int mode) {
416 mPowerMode = mode;
417 }
418
419 int DisplayDevice::getPowerMode() const {
420 return mPowerMode;
421 }
422
423 bool DisplayDevice::isDisplayOn() const {
424 return (mPowerMode != HWC_POWER_MODE_OFF);
425 }
426
427 // ----------------------------------------------------------------------------
428 void DisplayDevice::setActiveConfig(int mode) {
429 mActiveConfig = mode;
430 }
431
432 int DisplayDevice::getActiveConfig() const {
433 return mActiveConfig;
434 }
435
436 // ----------------------------------------------------------------------------
437 #ifdef USE_HWC2
438 void DisplayDevice::setActiveColorMode(android_color_mode_t mode) {
439 mActiveColorMode = mode;
440 }
441
442 android_color_mode_t DisplayDevice::getActiveColorMode() const {
443 return mActiveColorMode;
444 }
445 #endif
446
447 // ----------------------------------------------------------------------------
448
449 void DisplayDevice::setLayerStack(uint32_t stack) {
450 mLayerStack = stack;
451 dirtyRegion.set(bounds());
452 }
453
454 // ----------------------------------------------------------------------------
455
456 uint32_t DisplayDevice::getOrientationTransform() const {
457 uint32_t transform = 0;
458 switch (mOrientation) {
459 case DisplayState::eOrientationDefault:
460 transform = Transform::ROT_0;
461 break;
462 case DisplayState::eOrientation90:
463 transform = Transform::ROT_90;
464 break;
465 case DisplayState::eOrientation180:
466 transform = Transform::ROT_180;
467 break;
468 case DisplayState::eOrientation270:
469 transform = Transform::ROT_270;
470 break;
471 }
472 return transform;
473 }
474
475 status_t DisplayDevice::orientationToTransfrom(
476 int orientation, int w, int h, Transform* tr)
477 {
478 uint32_t flags = 0;
479 switch (orientation) {
480 case DisplayState::eOrientationDefault:
481 flags = Transform::ROT_0;
482 break;
483 case DisplayState::eOrientation90:
484 flags = Transform::ROT_90;
485 break;
486 case DisplayState::eOrientation180:
487 flags = Transform::ROT_180;
488 break;
489 case DisplayState::eOrientation270:
490 flags = Transform::ROT_270;
491 break;
492 default:
493 return BAD_VALUE;
494 }
495 tr->set(flags, w, h);
496 return NO_ERROR;
497 }
498
499 void DisplayDevice::setDisplaySize(const int newWidth, const int newHeight) {
500 dirtyRegion.set(getBounds());
501
502 if (mSurface != EGL_NO_SURFACE) {
503 eglDestroySurface(mDisplay, mSurface);
504 mSurface = EGL_NO_SURFACE;
505 }
506
507 mDisplaySurface->resizeBuffers(newWidth, newHeight);
508
509 ANativeWindow* const window = mNativeWindow.get();
510 mSurface = eglCreateWindowSurface(mDisplay, mConfig, window, NULL);
511 eglQuerySurface(mDisplay, mSurface, EGL_WIDTH, &mDisplayWidth);
512 eglQuerySurface(mDisplay, mSurface, EGL_HEIGHT, &mDisplayHeight);
513
514 LOG_FATAL_IF(mDisplayWidth != newWidth,
515 "Unable to set new width to %d", newWidth);
516 LOG_FATAL_IF(mDisplayHeight != newHeight,
517 "Unable to set new height to %d", newHeight);
518 }
519
520 void DisplayDevice::setProjection(int orientation,
521 const Rect& newViewport, const Rect& newFrame) {
522 Rect viewport(newViewport);
523 Rect frame(newFrame);
524
525 const int w = mDisplayWidth;
526 const int h = mDisplayHeight;
527
528 Transform R;
529 DisplayDevice::orientationToTransfrom(orientation, w, h, &R);
530
531 if (!frame.isValid()) {
532 // the destination frame can be invalid if it has never been set,
533 // in that case we assume the whole display frame.
534 frame = Rect(w, h);
535 }
536
537 if (viewport.isEmpty()) {
538 // viewport can be invalid if it has never been set, in that case
539 // we assume the whole display size.
540 // it's also invalid to have an empty viewport, so we handle that
541 // case in the same way.
542 viewport = Rect(w, h);
543 if (R.getOrientation() & Transform::ROT_90) {
544 // viewport is always specified in the logical orientation
545 // of the display (ie: post-rotation).
546 swap(viewport.right, viewport.bottom);
547 }
548 }
549
550 dirtyRegion.set(getBounds());
551
552 Transform TL, TP, S;
553 float src_width = viewport.width();
554 float src_height = viewport.height();
555 float dst_width = frame.width();
556 float dst_height = frame.height();
557 if (src_width != dst_width || src_height != dst_height) {
558 float sx = dst_width / src_width;
559 float sy = dst_height / src_height;
560 S.set(sx, 0, 0, sy);
561 }
562
563 float src_x = viewport.left;
564 float src_y = viewport.top;
565 float dst_x = frame.left;
566 float dst_y = frame.top;
567 TL.set(-src_x, -src_y);
568 TP.set(dst_x, dst_y);
569
570 // The viewport and frame are both in the logical orientation.
571 // Apply the logical translation, scale to physical size, apply the
572 // physical translation and finally rotate to the physical orientation.
573 mGlobalTransform = R * TP * S * TL;
574
575 const uint8_t type = mGlobalTransform.getType();
576 mNeedsFiltering = (!mGlobalTransform.preserveRects() ||
577 (type >= Transform::SCALE));
578
579 mScissor = mGlobalTransform.transform(viewport);
580 if (mScissor.isEmpty()) {
581 mScissor = getBounds();
582 }
583
584 mOrientation = orientation;
585 if (mType == DisplayType::DISPLAY_PRIMARY) {
586 uint32_t transform = 0;
587 switch (mOrientation) {
588 case DisplayState::eOrientationDefault:
589 transform = Transform::ROT_0;
590 break;
591 case DisplayState::eOrientation90:
592 transform = Transform::ROT_90;
593 break;
594 case DisplayState::eOrientation180:
595 transform = Transform::ROT_180;
596 break;
597 case DisplayState::eOrientation270:
598 transform = Transform::ROT_270;
599 break;
600 }
601 sPrimaryDisplayOrientation = transform;
602 }
603 mViewport = viewport;
604 mFrame = frame;
605 }
606
607 uint32_t DisplayDevice::getPrimaryDisplayOrientationTransform() {
608 return sPrimaryDisplayOrientation;
609 }
610
611 void DisplayDevice::dump(String8& result) const {
612 const Transform& tr(mGlobalTransform);
613 result.appendFormat(
614 "+ DisplayDevice: %s\n"
615 " type=%x, hwcId=%d, layerStack=%u, (%4dx%4d), ANativeWindow=%p, orient=%2d (type=%08x), "
616 "flips=%u, isSecure=%d, powerMode=%d, activeConfig=%d, numLayers=%zu\n"
617 " v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d],"
618 "transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n",
619 mDisplayName.string(), mType, mHwcDisplayId,
620 mLayerStack, mDisplayWidth, mDisplayHeight, mNativeWindow.get(),
621 mOrientation, tr.getType(), getPageFlipCount(),
622 mIsSecure, mPowerMode, mActiveConfig,
623 mVisibleLayersSortedByZ.size(),
624 mViewport.left, mViewport.top, mViewport.right, mViewport.bottom,
625 mFrame.left, mFrame.top, mFrame.right, mFrame.bottom,
626 mScissor.left, mScissor.top, mScissor.right, mScissor.bottom,
627 tr[0][0], tr[1][0], tr[2][0],
628 tr[0][1], tr[1][1], tr[2][1],
629 tr[0][2], tr[1][2], tr[2][2]);
630
631 String8 surfaceDump;
632 mDisplaySurface->dumpAsString(surfaceDump);
633 result.append(surfaceDump);
634 }
635
636 std::atomic<int32_t> DisplayDeviceState::nextDisplayId(1);
637
638 DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type, bool isSecure)
639 : type(type),
640 layerStack(DisplayDevice::NO_LAYER_STACK),
641 orientation(0),
642 width(0),
643 height(0),
644 isSecure(isSecure)
645 {
646 viewport.makeInvalid();
647 frame.makeInvalid();
648 }
649