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