OSDN Git Service

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