OSDN Git Service

Fix virtual displays for HWC<=1.1
[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 <GLES/gl.h>
33 #include <EGL/egl.h>
34 #include <EGL/eglext.h>
35
36 #include <hardware/gralloc.h>
37
38 #include "DisplayHardware/DisplaySurface.h"
39 #include "DisplayHardware/HWComposer.h"
40
41 #include "clz.h"
42 #include "DisplayDevice.h"
43 #include "GLExtensions.h"
44 #include "SurfaceFlinger.h"
45 #include "Layer.h"
46
47 // ----------------------------------------------------------------------------
48 using namespace android;
49 // ----------------------------------------------------------------------------
50
51 static __attribute__((noinline))
52 void checkGLErrors()
53 {
54     do {
55         // there could be more than one error flag
56         GLenum error = glGetError();
57         if (error == GL_NO_ERROR)
58             break;
59         ALOGE("GL error 0x%04x", int(error));
60     } while(true);
61 }
62
63 // ----------------------------------------------------------------------------
64
65 /*
66  * Initialize the display to the specified values.
67  *
68  */
69
70 DisplayDevice::DisplayDevice(
71         const sp<SurfaceFlinger>& flinger,
72         DisplayType type,
73         int32_t hwcId,
74         bool isSecure,
75         const wp<IBinder>& displayToken,
76         const sp<DisplaySurface>& displaySurface,
77         EGLConfig config)
78     : mFlinger(flinger),
79       mType(type), mHwcDisplayId(hwcId),
80       mDisplayToken(displayToken),
81       mDisplaySurface(displaySurface),
82       mDisplay(EGL_NO_DISPLAY),
83       mSurface(EGL_NO_SURFACE),
84       mContext(EGL_NO_CONTEXT),
85       mDisplayWidth(), mDisplayHeight(), mFormat(),
86       mFlags(),
87       mPageFlipCount(),
88       mIsSecure(isSecure),
89       mSecureLayerVisible(false),
90       mScreenAcquired(false),
91       mLayerStack(NO_LAYER_STACK),
92       mOrientation()
93 {
94     mNativeWindow = new Surface(mDisplaySurface->getIGraphicBufferProducer());
95     ANativeWindow* const window = mNativeWindow.get();
96
97     int format;
98     window->query(window, NATIVE_WINDOW_FORMAT, &format);
99
100     /*
101      * Create our display's surface
102      */
103
104     EGLSurface surface;
105     EGLint w, h;
106     EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
107     surface = eglCreateWindowSurface(display, config, window, NULL);
108     eglQuerySurface(display, surface, EGL_WIDTH,  &mDisplayWidth);
109     eglQuerySurface(display, surface, EGL_HEIGHT, &mDisplayHeight);
110
111     mDisplay = display;
112     mSurface = surface;
113     mFormat  = format;
114     mPageFlipCount = 0;
115     mViewport.makeInvalid();
116     mFrame.makeInvalid();
117
118     // virtual displays are always considered enabled
119     mScreenAcquired = (mType >= DisplayDevice::DISPLAY_VIRTUAL);
120
121     // Name the display.  The name will be replaced shortly if the display
122     // was created with createDisplay().
123     switch (mType) {
124         case DISPLAY_PRIMARY:
125             mDisplayName = "Built-in Screen";
126             break;
127         case DISPLAY_EXTERNAL:
128             mDisplayName = "HDMI Screen";
129             break;
130         default:
131             mDisplayName = "Virtual Screen";    // e.g. Overlay #n
132             break;
133     }
134
135     // initialize the display orientation transform.
136     setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);
137 }
138
139 DisplayDevice::~DisplayDevice() {
140     if (mSurface != EGL_NO_SURFACE) {
141         eglDestroySurface(mDisplay, mSurface);
142         mSurface = EGL_NO_SURFACE;
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     checkGLErrors();
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 void DisplayDevice::swapBuffers(HWComposer& hwc) const {
201     // We need to call eglSwapBuffers() unless:
202     // (a) there was no GLES composition this frame, or
203     // (b) we're using a legacy HWC with no framebuffer target support (in
204     //     which case HWComposer::commit() handles things).
205     if (hwc.initCheck() != NO_ERROR ||
206             (hwc.hasGlesComposition(mHwcDisplayId) &&
207              hwc.supportsFramebufferTarget())) {
208         EGLBoolean success = eglSwapBuffers(mDisplay, mSurface);
209         if (!success) {
210             EGLint error = eglGetError();
211             if (error == EGL_CONTEXT_LOST ||
212                     mType == DisplayDevice::DISPLAY_PRIMARY) {
213                 LOG_ALWAYS_FATAL("eglSwapBuffers(%p, %p) failed with 0x%08x",
214                         mDisplay, mSurface, error);
215             } else {
216                 ALOGE("eglSwapBuffers(%p, %p) failed with 0x%08x",
217                         mDisplay, mSurface, error);
218             }
219         }
220     }
221
222     status_t result = mDisplaySurface->advanceFrame();
223     if (result != NO_ERROR) {
224         ALOGE("[%s] failed pushing new frame to HWC: %d",
225                 mDisplayName.string(), result);
226     }
227 }
228
229 void DisplayDevice::onSwapBuffersCompleted(HWComposer& hwc) const {
230     if (hwc.initCheck() == NO_ERROR) {
231         mDisplaySurface->onFrameCommitted();
232     }
233 }
234
235 uint32_t DisplayDevice::getFlags() const
236 {
237     return mFlags;
238 }
239
240 EGLBoolean DisplayDevice::makeCurrent(EGLDisplay dpy,
241         const sp<const DisplayDevice>& hw, EGLContext ctx) {
242     EGLBoolean result = EGL_TRUE;
243     EGLSurface sur = eglGetCurrentSurface(EGL_DRAW);
244     if (sur != hw->mSurface) {
245         result = eglMakeCurrent(dpy, hw->mSurface, hw->mSurface, ctx);
246         if (result == EGL_TRUE) {
247             setViewportAndProjection(hw);
248         }
249     }
250     return result;
251 }
252
253 void DisplayDevice::setViewportAndProjection(const sp<const DisplayDevice>& hw) {
254     GLsizei w = hw->mDisplayWidth;
255     GLsizei h = hw->mDisplayHeight;
256     glViewport(0, 0, w, h);
257     glMatrixMode(GL_PROJECTION);
258     glLoadIdentity();
259     // put the origin in the left-bottom corner
260     glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h
261     glMatrixMode(GL_MODELVIEW);
262 }
263
264 // ----------------------------------------------------------------------------
265
266 void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers) {
267     mVisibleLayersSortedByZ = layers;
268     mSecureLayerVisible = false;
269     size_t count = layers.size();
270     for (size_t i=0 ; i<count ; i++) {
271         const sp<Layer>& layer(layers[i]);
272         if (layer->isSecure()) {
273             mSecureLayerVisible = true;
274         }
275     }
276 }
277
278 const Vector< sp<Layer> >& DisplayDevice::getVisibleLayersSortedByZ() const {
279     return mVisibleLayersSortedByZ;
280 }
281
282 bool DisplayDevice::getSecureLayerVisible() const {
283     return mSecureLayerVisible;
284 }
285
286 Region DisplayDevice::getDirtyRegion(bool repaintEverything) const {
287     Region dirty;
288     if (repaintEverything) {
289         dirty.set(getBounds());
290     } else {
291         const Transform& planeTransform(mGlobalTransform);
292         dirty = planeTransform.transform(this->dirtyRegion);
293         dirty.andSelf(getBounds());
294     }
295     return dirty;
296 }
297
298 // ----------------------------------------------------------------------------
299
300 bool DisplayDevice::canDraw() const {
301     return mScreenAcquired;
302 }
303
304 void DisplayDevice::releaseScreen() const {
305     mScreenAcquired = false;
306 }
307
308 void DisplayDevice::acquireScreen() const {
309     mScreenAcquired = true;
310 }
311
312 bool DisplayDevice::isScreenAcquired() const {
313     return mScreenAcquired;
314 }
315
316 // ----------------------------------------------------------------------------
317
318 void DisplayDevice::setLayerStack(uint32_t stack) {
319     mLayerStack = stack;
320     dirtyRegion.set(bounds());
321 }
322
323 // ----------------------------------------------------------------------------
324
325 status_t DisplayDevice::orientationToTransfrom(
326         int orientation, int w, int h, Transform* tr)
327 {
328     uint32_t flags = 0;
329     switch (orientation) {
330     case DisplayState::eOrientationDefault:
331         flags = Transform::ROT_0;
332         break;
333     case DisplayState::eOrientation90:
334         flags = Transform::ROT_90;
335         break;
336     case DisplayState::eOrientation180:
337         flags = Transform::ROT_180;
338         break;
339     case DisplayState::eOrientation270:
340         flags = Transform::ROT_270;
341         break;
342     default:
343         return BAD_VALUE;
344     }
345     tr->set(flags, w, h);
346     return NO_ERROR;
347 }
348
349 void DisplayDevice::setProjection(int orientation,
350         const Rect& newViewport, const Rect& newFrame) {
351     Rect viewport(newViewport);
352     Rect frame(newFrame);
353
354     const int w = mDisplayWidth;
355     const int h = mDisplayHeight;
356
357     Transform R;
358     DisplayDevice::orientationToTransfrom(orientation, w, h, &R);
359
360     if (!frame.isValid()) {
361         // the destination frame can be invalid if it has never been set,
362         // in that case we assume the whole display frame.
363         frame = Rect(w, h);
364     }
365
366     if (viewport.isEmpty()) {
367         // viewport can be invalid if it has never been set, in that case
368         // we assume the whole display size.
369         // it's also invalid to have an empty viewport, so we handle that
370         // case in the same way.
371         viewport = Rect(w, h);
372         if (R.getOrientation() & Transform::ROT_90) {
373             // viewport is always specified in the logical orientation
374             // of the display (ie: post-rotation).
375             swap(viewport.right, viewport.bottom);
376         }
377     }
378
379     dirtyRegion.set(getBounds());
380
381     Transform TL, TP, S;
382     float src_width  = viewport.width();
383     float src_height = viewport.height();
384     float dst_width  = frame.width();
385     float dst_height = frame.height();
386     if (src_width != dst_width || src_height != dst_height) {
387         float sx = dst_width  / src_width;
388         float sy = dst_height / src_height;
389         S.set(sx, 0, 0, sy);
390     }
391
392     float src_x = viewport.left;
393     float src_y = viewport.top;
394     float dst_x = frame.left;
395     float dst_y = frame.top;
396     TL.set(-src_x, -src_y);
397     TP.set(dst_x, dst_y);
398
399     // The viewport and frame are both in the logical orientation.
400     // Apply the logical translation, scale to physical size, apply the
401     // physical translation and finally rotate to the physical orientation.
402     mGlobalTransform = R * TP * S * TL;
403
404     const uint8_t type = mGlobalTransform.getType();
405     mNeedsFiltering = (!mGlobalTransform.preserveRects() ||
406             (type >= Transform::SCALE));
407
408     mScissor = mGlobalTransform.transform(viewport);
409     if (mScissor.isEmpty()) {
410         mScissor.set(getBounds());
411     }
412
413     mOrientation = orientation;
414     mViewport = viewport;
415     mFrame = frame;
416 }
417
418 void DisplayDevice::dump(String8& result, char* buffer, size_t SIZE) const {
419     const Transform& tr(mGlobalTransform);
420     snprintf(buffer, SIZE,
421         "+ DisplayDevice: %s\n"
422         "   type=%x, layerStack=%u, (%4dx%4d), ANativeWindow=%p, orient=%2d (type=%08x), "
423         "flips=%u, isSecure=%d, secureVis=%d, acquired=%d, numLayers=%u\n"
424         "   v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d],"
425         "transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n",
426         mDisplayName.string(), mType,
427         mLayerStack, mDisplayWidth, mDisplayHeight, mNativeWindow.get(),
428         mOrientation, tr.getType(), getPageFlipCount(),
429         mIsSecure, mSecureLayerVisible, mScreenAcquired, mVisibleLayersSortedByZ.size(),
430         mViewport.left, mViewport.top, mViewport.right, mViewport.bottom,
431         mFrame.left, mFrame.top, mFrame.right, mFrame.bottom,
432         mScissor.left, mScissor.top, mScissor.right, mScissor.bottom,
433         tr[0][0], tr[1][0], tr[2][0],
434         tr[0][1], tr[1][1], tr[2][1],
435         tr[0][2], tr[1][2], tr[2][2]);
436
437     result.append(buffer);
438
439     String8 surfaceDump;
440     mDisplaySurface->dump(surfaceDump);
441     result.append(surfaceDump);
442 }