2 * Copyright (C) 2007 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include <cutils/properties.h>
24 #include <utils/RefBase.h>
25 #include <utils/Log.h>
27 #include <ui/DisplayInfo.h>
28 #include <ui/PixelFormat.h>
30 #include <gui/Surface.h>
32 #include <hardware/gralloc.h>
34 #include "DisplayHardware/DisplaySurface.h"
35 #include "DisplayHardware/HWComposer.h"
36 #include "RenderEngine/RenderEngine.h"
39 #include "DisplayDevice.h"
40 #include "SurfaceFlinger.h"
43 // ----------------------------------------------------------------------------
44 using namespace android;
45 // ----------------------------------------------------------------------------
48 * Initialize the display to the specified values.
52 DisplayDevice::DisplayDevice(
53 const sp<SurfaceFlinger>& flinger,
58 const wp<IBinder>& displayToken,
59 const sp<DisplaySurface>& displaySurface,
60 const sp<IGraphicBufferProducer>& producer,
62 : lastCompositionHadVisibleLayers(false),
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(),
73 mSecureLayerVisible(false),
74 mLayerStack(NO_LAYER_STACK),
76 mPowerMode(HWC_POWER_MODE_OFF),
79 mNativeWindow = new Surface(producer, false);
80 ANativeWindow* const window = mNativeWindow.get();
83 * Create our display's surface
88 EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
89 if (config == EGL_NO_CONFIG) {
90 config = RenderEngine::chooseEglConfig(display, format);
92 surface = eglCreateWindowSurface(display, config, window, NULL);
93 eglQuerySurface(display, surface, EGL_WIDTH, &mDisplayWidth);
94 eglQuerySurface(display, surface, EGL_HEIGHT, &mDisplayHeight);
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
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);
111 mViewport.makeInvalid();
112 mFrame.makeInvalid();
114 // virtual displays are always considered enabled
115 mPowerMode = (mType >= DisplayDevice::DISPLAY_VIRTUAL) ?
116 HWC_POWER_MODE_NORMAL : HWC_POWER_MODE_OFF;
118 // Name the display. The name will be replaced shortly if the display
119 // was created with createDisplay().
121 case DISPLAY_PRIMARY:
122 mDisplayName = "Built-in Screen";
124 case DISPLAY_EXTERNAL:
125 mDisplayName = "HDMI Screen";
128 mDisplayName = "Virtual Screen"; // e.g. Overlay #n
132 // initialize the display orientation transform.
133 setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);
136 DisplayDevice::~DisplayDevice() {
137 if (mSurface != EGL_NO_SURFACE) {
138 eglDestroySurface(mDisplay, mSurface);
139 mSurface = EGL_NO_SURFACE;
143 void DisplayDevice::disconnect(HWComposer& hwc) {
144 if (mHwcDisplayId >= 0) {
145 hwc.disconnectDisplay(mHwcDisplayId);
146 if (mHwcDisplayId >= DISPLAY_VIRTUAL)
147 hwc.freeDisplayId(mHwcDisplayId);
152 bool DisplayDevice::isValid() const {
153 return mFlinger != NULL;
156 int DisplayDevice::getWidth() const {
157 return mDisplayWidth;
160 int DisplayDevice::getHeight() const {
161 return mDisplayHeight;
164 PixelFormat DisplayDevice::getFormat() const {
168 EGLSurface DisplayDevice::getEGLSurface() const {
172 void DisplayDevice::setDisplayName(const String8& displayName) {
173 if (!displayName.isEmpty()) {
174 // never override the name with an empty name
175 mDisplayName = displayName;
179 uint32_t DisplayDevice::getPageFlipCount() const {
180 return mPageFlipCount;
183 status_t DisplayDevice::compositionComplete() const {
184 return mDisplaySurface->compositionComplete();
187 void DisplayDevice::flip(const Region& dirty) const
189 mFlinger->getRenderEngine().checkErrors();
191 EGLDisplay dpy = mDisplay;
192 EGLSurface surface = mSurface;
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());
202 (void) dirty; // Eliminate unused parameter warning
208 status_t DisplayDevice::beginFrame(bool mustRecompose) const {
209 return mDisplaySurface->beginFrame(mustRecompose);
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;
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;
228 return mDisplaySurface->prepareFrame(compositionType);
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);
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);
249 ALOGE("eglSwapBuffers(%p, %p) failed with 0x%08x",
250 mDisplay, mSurface, error);
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);
262 void DisplayDevice::onSwapBuffersCompleted(HWComposer& hwc) const {
263 if (hwc.initCheck() == NO_ERROR) {
264 mDisplaySurface->onFrameCommitted();
268 uint32_t DisplayDevice::getFlags() const
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);
283 setViewportAndProjection();
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, false);
294 // ----------------------------------------------------------------------------
296 void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers) {
297 mVisibleLayersSortedByZ = layers;
298 mSecureLayerVisible = false;
299 size_t count = layers.size();
300 for (size_t i=0 ; i<count ; i++) {
301 const sp<Layer>& layer(layers[i]);
302 if (layer->isSecure()) {
303 mSecureLayerVisible = true;
308 const Vector< sp<Layer> >& DisplayDevice::getVisibleLayersSortedByZ() const {
309 return mVisibleLayersSortedByZ;
312 bool DisplayDevice::getSecureLayerVisible() const {
313 return mSecureLayerVisible;
316 Region DisplayDevice::getDirtyRegion(bool repaintEverything) const {
318 if (repaintEverything) {
319 dirty.set(getBounds());
321 const Transform& planeTransform(mGlobalTransform);
322 dirty = planeTransform.transform(this->dirtyRegion);
323 dirty.andSelf(getBounds());
328 // ----------------------------------------------------------------------------
329 void DisplayDevice::setPowerMode(int mode) {
333 int DisplayDevice::getPowerMode() const {
337 bool DisplayDevice::isDisplayOn() const {
338 return (mPowerMode != HWC_POWER_MODE_OFF);
341 // ----------------------------------------------------------------------------
342 void DisplayDevice::setActiveConfig(int mode) {
343 mActiveConfig = mode;
346 int DisplayDevice::getActiveConfig() const {
347 return mActiveConfig;
350 // ----------------------------------------------------------------------------
352 void DisplayDevice::setLayerStack(uint32_t stack) {
354 dirtyRegion.set(bounds());
357 // ----------------------------------------------------------------------------
359 uint32_t DisplayDevice::getOrientationTransform() const {
360 uint32_t transform = 0;
361 switch (mOrientation) {
362 case DisplayState::eOrientationDefault:
363 transform = Transform::ROT_0;
365 case DisplayState::eOrientation90:
366 transform = Transform::ROT_90;
368 case DisplayState::eOrientation180:
369 transform = Transform::ROT_180;
371 case DisplayState::eOrientation270:
372 transform = Transform::ROT_270;
378 status_t DisplayDevice::orientationToTransfrom(
379 int orientation, int w, int h, Transform* tr)
382 switch (orientation) {
383 case DisplayState::eOrientationDefault:
384 flags = Transform::ROT_0;
386 case DisplayState::eOrientation90:
387 flags = Transform::ROT_90;
389 case DisplayState::eOrientation180:
390 flags = Transform::ROT_180;
392 case DisplayState::eOrientation270:
393 flags = Transform::ROT_270;
398 tr->set(flags, w, h);
402 void DisplayDevice::setDisplaySize(const int newWidth, const int newHeight) {
403 dirtyRegion.set(getBounds());
405 if (mSurface != EGL_NO_SURFACE) {
406 eglDestroySurface(mDisplay, mSurface);
407 mSurface = EGL_NO_SURFACE;
410 mDisplaySurface->resizeBuffers(newWidth, newHeight);
412 ANativeWindow* const window = mNativeWindow.get();
413 mSurface = eglCreateWindowSurface(mDisplay, mConfig, window, NULL);
414 eglQuerySurface(mDisplay, mSurface, EGL_WIDTH, &mDisplayWidth);
415 eglQuerySurface(mDisplay, mSurface, EGL_HEIGHT, &mDisplayHeight);
417 LOG_FATAL_IF(mDisplayWidth != newWidth,
418 "Unable to set new width to %d", newWidth);
419 LOG_FATAL_IF(mDisplayHeight != newHeight,
420 "Unable to set new height to %d", newHeight);
423 void DisplayDevice::setProjection(int orientation,
424 const Rect& newViewport, const Rect& newFrame) {
425 Rect viewport(newViewport);
426 Rect frame(newFrame);
428 const int w = mDisplayWidth;
429 const int h = mDisplayHeight;
432 DisplayDevice::orientationToTransfrom(orientation, w, h, &R);
434 if (!frame.isValid()) {
435 // the destination frame can be invalid if it has never been set,
436 // in that case we assume the whole display frame.
440 if (viewport.isEmpty()) {
441 // viewport can be invalid if it has never been set, in that case
442 // we assume the whole display size.
443 // it's also invalid to have an empty viewport, so we handle that
444 // case in the same way.
445 viewport = Rect(w, h);
446 if (R.getOrientation() & Transform::ROT_90) {
447 // viewport is always specified in the logical orientation
448 // of the display (ie: post-rotation).
449 swap(viewport.right, viewport.bottom);
453 dirtyRegion.set(getBounds());
456 float src_width = viewport.width();
457 float src_height = viewport.height();
458 float dst_width = frame.width();
459 float dst_height = frame.height();
460 if (src_width != dst_width || src_height != dst_height) {
461 float sx = dst_width / src_width;
462 float sy = dst_height / src_height;
466 float src_x = viewport.left;
467 float src_y = viewport.top;
468 float dst_x = frame.left;
469 float dst_y = frame.top;
470 TL.set(-src_x, -src_y);
471 TP.set(dst_x, dst_y);
473 // The viewport and frame are both in the logical orientation.
474 // Apply the logical translation, scale to physical size, apply the
475 // physical translation and finally rotate to the physical orientation.
476 mGlobalTransform = R * TP * S * TL;
478 const uint8_t type = mGlobalTransform.getType();
479 mNeedsFiltering = (!mGlobalTransform.preserveRects() ||
480 (type >= Transform::SCALE));
482 mScissor = mGlobalTransform.transform(viewport);
483 if (mScissor.isEmpty()) {
484 mScissor = getBounds();
487 mOrientation = orientation;
488 mViewport = viewport;
492 void DisplayDevice::dump(String8& result) const {
493 const Transform& tr(mGlobalTransform);
495 "+ DisplayDevice: %s\n"
496 " type=%x, hwcId=%d, layerStack=%u, (%4dx%4d), ANativeWindow=%p, orient=%2d (type=%08x), "
497 "flips=%u, isSecure=%d, secureVis=%d, powerMode=%d, activeConfig=%d, numLayers=%zu\n"
498 " v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d],"
499 "transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n",
500 mDisplayName.string(), mType, mHwcDisplayId,
501 mLayerStack, mDisplayWidth, mDisplayHeight, mNativeWindow.get(),
502 mOrientation, tr.getType(), getPageFlipCount(),
503 mIsSecure, mSecureLayerVisible, mPowerMode, mActiveConfig,
504 mVisibleLayersSortedByZ.size(),
505 mViewport.left, mViewport.top, mViewport.right, mViewport.bottom,
506 mFrame.left, mFrame.top, mFrame.right, mFrame.bottom,
507 mScissor.left, mScissor.top, mScissor.right, mScissor.bottom,
508 tr[0][0], tr[1][0], tr[2][0],
509 tr[0][1], tr[1][1], tr[2][1],
510 tr[0][2], tr[1][2], tr[2][2]);
513 mDisplaySurface->dump(surfaceDump);
514 result.append(surfaceDump);