OSDN Git Service

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