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