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