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 #ifdef USE_HWC2
419 void DisplayDevice::setActiveColorMode(android_color_mode_t mode) {
420 mActiveColorMode = mode;
421 }
422
423 android_color_mode_t DisplayDevice::getActiveColorMode() const {
424 return mActiveColorMode;
425 }
426 #endif
427
428 // ----------------------------------------------------------------------------
429
430 void DisplayDevice::setLayerStack(uint32_t stack) {
431 mLayerStack = stack;
432 dirtyRegion.set(bounds());
433 }
434
435 // ----------------------------------------------------------------------------
436
437 uint32_t DisplayDevice::getOrientationTransform() const {
438 uint32_t transform = 0;
439 switch (mOrientation) {
440 case DisplayState::eOrientationDefault:
441 transform = Transform::ROT_0;
442 break;
443 case DisplayState::eOrientation90:
444 transform = Transform::ROT_90;
445 break;
446 case DisplayState::eOrientation180:
447 transform = Transform::ROT_180;
448 break;
449 case DisplayState::eOrientation270:
450 transform = Transform::ROT_270;
451 break;
452 }
453 return transform;
454 }
455
456 status_t DisplayDevice::orientationToTransfrom(
457 int orientation, int w, int h, Transform* tr)
458 {
459 uint32_t flags = 0;
460 switch (orientation) {
461 case DisplayState::eOrientationDefault:
462 flags = Transform::ROT_0;
463 break;
464 case DisplayState::eOrientation90:
465 flags = Transform::ROT_90;
466 break;
467 case DisplayState::eOrientation180:
468 flags = Transform::ROT_180;
469 break;
470 case DisplayState::eOrientation270:
471 flags = Transform::ROT_270;
472 break;
473 default:
474 return BAD_VALUE;
475 }
476 tr->set(flags, w, h);
477 return NO_ERROR;
478 }
479
480 void DisplayDevice::setDisplaySize(const int newWidth, const int newHeight) {
481 dirtyRegion.set(getBounds());
482
483 if (mSurface != EGL_NO_SURFACE) {
484 eglDestroySurface(mDisplay, mSurface);
485 mSurface = EGL_NO_SURFACE;
486 }
487
488 mDisplaySurface->resizeBuffers(newWidth, newHeight);
489
490 ANativeWindow* const window = mNativeWindow.get();
491 mSurface = eglCreateWindowSurface(mDisplay, mConfig, window, NULL);
492 eglQuerySurface(mDisplay, mSurface, EGL_WIDTH, &mDisplayWidth);
493 eglQuerySurface(mDisplay, mSurface, EGL_HEIGHT, &mDisplayHeight);
494
495 LOG_FATAL_IF(mDisplayWidth != newWidth,
496 "Unable to set new width to %d", newWidth);
497 LOG_FATAL_IF(mDisplayHeight != newHeight,
498 "Unable to set new height to %d", newHeight);
499 }
500
501 void DisplayDevice::setProjection(int orientation,
502 const Rect& newViewport, const Rect& newFrame) {
503 Rect viewport(newViewport);
504 Rect frame(newFrame);
505
506 const int w = mDisplayWidth;
507 const int h = mDisplayHeight;
508
509 Transform R;
510 DisplayDevice::orientationToTransfrom(orientation, w, h, &R);
511
512 if (!frame.isValid()) {
513 // the destination frame can be invalid if it has never been set,
514 // in that case we assume the whole display frame.
515 frame = Rect(w, h);
516 }
517
518 if (viewport.isEmpty()) {
519 // viewport can be invalid if it has never been set, in that case
520 // we assume the whole display size.
521 // it's also invalid to have an empty viewport, so we handle that
522 // case in the same way.
523 viewport = Rect(w, h);
524 if (R.getOrientation() & Transform::ROT_90) {
525 // viewport is always specified in the logical orientation
526 // of the display (ie: post-rotation).
527 swap(viewport.right, viewport.bottom);
528 }
529 }
530
531 dirtyRegion.set(getBounds());
532
533 Transform TL, TP, S;
534 float src_width = viewport.width();
535 float src_height = viewport.height();
536 float dst_width = frame.width();
537 float dst_height = frame.height();
538 if (src_width != dst_width || src_height != dst_height) {
539 float sx = dst_width / src_width;
540 float sy = dst_height / src_height;
541 S.set(sx, 0, 0, sy);
542 }
543
544 float src_x = viewport.left;
545 float src_y = viewport.top;
546 float dst_x = frame.left;
547 float dst_y = frame.top;
548 TL.set(-src_x, -src_y);
549 TP.set(dst_x, dst_y);
550
551 // The viewport and frame are both in the logical orientation.
552 // Apply the logical translation, scale to physical size, apply the
553 // physical translation and finally rotate to the physical orientation.
554 mGlobalTransform = R * TP * S * TL;
555
556 const uint8_t type = mGlobalTransform.getType();
557 mNeedsFiltering = (!mGlobalTransform.preserveRects() ||
558 (type >= Transform::SCALE));
559
560 mScissor = mGlobalTransform.transform(viewport);
561 if (mScissor.isEmpty()) {
562 mScissor = getBounds();
563 }
564
565 mOrientation = orientation;
566 if (mType == DisplayType::DISPLAY_PRIMARY) {
567 uint32_t transform = 0;
568 switch (mOrientation) {
569 case DisplayState::eOrientationDefault:
570 transform = Transform::ROT_0;
571 break;
572 case DisplayState::eOrientation90:
573 transform = Transform::ROT_90;
574 break;
575 case DisplayState::eOrientation180:
576 transform = Transform::ROT_180;
577 break;
578 case DisplayState::eOrientation270:
579 transform = Transform::ROT_270;
580 break;
581 }
582 sPrimaryDisplayOrientation = transform;
583 }
584 mViewport = viewport;
585 mFrame = frame;
586 }
587
588 uint32_t DisplayDevice::getPrimaryDisplayOrientationTransform() {
589 return sPrimaryDisplayOrientation;
590 }
591
592 void DisplayDevice::dump(String8& result) const {
593 const Transform& tr(mGlobalTransform);
594 result.appendFormat(
595 "+ DisplayDevice: %s\n"
596 " type=%x, hwcId=%d, layerStack=%u, (%4dx%4d), ANativeWindow=%p, orient=%2d (type=%08x), "
597 "flips=%u, isSecure=%d, powerMode=%d, activeConfig=%d, numLayers=%zu\n"
598 " v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d],"
599 "transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n",
600 mDisplayName.string(), mType, mHwcDisplayId,
601 mLayerStack, mDisplayWidth, mDisplayHeight, mNativeWindow.get(),
602 mOrientation, tr.getType(), getPageFlipCount(),
603 mIsSecure, mPowerMode, mActiveConfig,
604 mVisibleLayersSortedByZ.size(),
605 mViewport.left, mViewport.top, mViewport.right, mViewport.bottom,
606 mFrame.left, mFrame.top, mFrame.right, mFrame.bottom,
607 mScissor.left, mScissor.top, mScissor.right, mScissor.bottom,
608 tr[0][0], tr[1][0], tr[2][0],
609 tr[0][1], tr[1][1], tr[2][1],
610 tr[0][2], tr[1][2], tr[2][2]);
611
612 String8 surfaceDump;
613 mDisplaySurface->dumpAsString(surfaceDump);
614 result.append(surfaceDump);
615 }
616