OSDN Git Service

Merge "Add rotation to surfaceflingers screen cap." into lmp-dev
[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 /*
48  * Initialize the display to the specified values.
49  *
50  */
51
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
136 DisplayDevice::~DisplayDevice() {
137     if (mSurface != EGL_NO_SURFACE) {
138         eglDestroySurface(mDisplay, mSurface);
139         mSurface = EGL_NO_SURFACE;
140     }
141 }
142
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
152 bool DisplayDevice::isValid() const {
153     return mFlinger != NULL;
154 }
155
156 int DisplayDevice::getWidth() const {
157     return mDisplayWidth;
158 }
159
160 int DisplayDevice::getHeight() const {
161     return mDisplayHeight;
162 }
163
164 PixelFormat DisplayDevice::getFormat() const {
165     return mFormat;
166 }
167
168 EGLSurface DisplayDevice::getEGLSurface() const {
169     return mSurface;
170 }
171
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
179 uint32_t DisplayDevice::getPageFlipCount() const {
180     return mPageFlipCount;
181 }
182
183 status_t DisplayDevice::compositionComplete() const {
184     return mDisplaySurface->compositionComplete();
185 }
186
187 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
208 status_t DisplayDevice::beginFrame(bool mustRecompose) const {
209     return mDisplaySurface->beginFrame(mustRecompose);
210 }
211
212 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
231 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
262 void DisplayDevice::onSwapBuffersCompleted(HWComposer& hwc) const {
263     if (hwc.initCheck() == NO_ERROR) {
264         mDisplaySurface->onFrameCommitted();
265     }
266 }
267
268 uint32_t DisplayDevice::getFlags() const
269 {
270     return mFlags;
271 }
272
273 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
287 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
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
309 const Vector< sp<Layer> >& DisplayDevice::getVisibleLayersSortedByZ() const {
310     return mVisibleLayersSortedByZ;
311 }
312
313 bool DisplayDevice::getSecureLayerVisible() const {
314     return mSecureLayerVisible;
315 }
316
317 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 // ----------------------------------------------------------------------------
330 void DisplayDevice::setPowerMode(int mode) {
331     mPowerMode = mode;
332 }
333
334 int DisplayDevice::getPowerMode()  const {
335     return mPowerMode;
336 }
337
338 bool DisplayDevice::isDisplayOn() const {
339     return (mPowerMode != HWC_POWER_MODE_OFF);
340 }
341
342 // ----------------------------------------------------------------------------
343 void DisplayDevice::setActiveConfig(int mode) {
344     mActiveConfig = mode;
345 }
346
347 int DisplayDevice::getActiveConfig()  const {
348     return mActiveConfig;
349 }
350
351 // ----------------------------------------------------------------------------
352
353 void DisplayDevice::setLayerStack(uint32_t stack) {
354     mLayerStack = stack;
355     dirtyRegion.set(bounds());
356 }
357
358 // ----------------------------------------------------------------------------
359
360 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
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
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
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
493 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 }