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,
292 false, Transform::ROT_0);
295 // ----------------------------------------------------------------------------
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;
309 const Vector< sp<Layer> >& DisplayDevice::getVisibleLayersSortedByZ() const {
310 return mVisibleLayersSortedByZ;
313 bool DisplayDevice::getSecureLayerVisible() const {
314 return mSecureLayerVisible;
317 Region DisplayDevice::getDirtyRegion(bool repaintEverything) const {
319 if (repaintEverything) {
320 dirty.set(getBounds());
322 const Transform& planeTransform(mGlobalTransform);
323 dirty = planeTransform.transform(this->dirtyRegion);
324 dirty.andSelf(getBounds());
329 // ----------------------------------------------------------------------------
330 void DisplayDevice::setPowerMode(int mode) {
334 int DisplayDevice::getPowerMode() const {
338 bool DisplayDevice::isDisplayOn() const {
339 return (mPowerMode != HWC_POWER_MODE_OFF);
342 // ----------------------------------------------------------------------------
343 void DisplayDevice::setActiveConfig(int mode) {
344 mActiveConfig = mode;
347 int DisplayDevice::getActiveConfig() const {
348 return mActiveConfig;
351 // ----------------------------------------------------------------------------
353 void DisplayDevice::setLayerStack(uint32_t stack) {
355 dirtyRegion.set(bounds());
358 // ----------------------------------------------------------------------------
360 uint32_t DisplayDevice::getOrientationTransform() const {
361 uint32_t transform = 0;
362 switch (mOrientation) {
363 case DisplayState::eOrientationDefault:
364 transform = Transform::ROT_0;
366 case DisplayState::eOrientation90:
367 transform = Transform::ROT_90;
369 case DisplayState::eOrientation180:
370 transform = Transform::ROT_180;
372 case DisplayState::eOrientation270:
373 transform = Transform::ROT_270;
379 status_t DisplayDevice::orientationToTransfrom(
380 int orientation, int w, int h, Transform* tr)
383 switch (orientation) {
384 case DisplayState::eOrientationDefault:
385 flags = Transform::ROT_0;
387 case DisplayState::eOrientation90:
388 flags = Transform::ROT_90;
390 case DisplayState::eOrientation180:
391 flags = Transform::ROT_180;
393 case DisplayState::eOrientation270:
394 flags = Transform::ROT_270;
399 tr->set(flags, w, h);
403 void DisplayDevice::setDisplaySize(const int newWidth, const int newHeight) {
404 dirtyRegion.set(getBounds());
406 if (mSurface != EGL_NO_SURFACE) {
407 eglDestroySurface(mDisplay, mSurface);
408 mSurface = EGL_NO_SURFACE;
411 mDisplaySurface->resizeBuffers(newWidth, newHeight);
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);
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);
424 void DisplayDevice::setProjection(int orientation,
425 const Rect& newViewport, const Rect& newFrame) {
426 Rect viewport(newViewport);
427 Rect frame(newFrame);
429 const int w = mDisplayWidth;
430 const int h = mDisplayHeight;
433 DisplayDevice::orientationToTransfrom(orientation, w, h, &R);
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.
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);
454 dirtyRegion.set(getBounds());
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;
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);
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;
479 const uint8_t type = mGlobalTransform.getType();
480 mNeedsFiltering = (!mGlobalTransform.preserveRects() ||
481 (type >= Transform::SCALE));
483 mScissor = mGlobalTransform.transform(viewport);
484 if (mScissor.isEmpty()) {
485 mScissor = getBounds();
488 mOrientation = orientation;
489 mViewport = viewport;
493 void DisplayDevice::dump(String8& result) const {
494 const Transform& tr(mGlobalTransform);
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]);
514 mDisplaySurface->dump(surfaceDump);
515 result.append(surfaceDump);