• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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