blob: 88e0dd70e2867a076f57806c78a7b9b29c9c17cb [file] [log] [blame]
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001/*
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
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080017#include <stdlib.h>
18#include <stdio.h>
19#include <string.h>
20#include <math.h>
21
22#include <cutils/properties.h>
23
Mathias Agopian076b1cc2009-04-10 14:24:30 -070024#include <utils/RefBase.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080025#include <utils/Log.h>
26
Mathias Agopianc666cae2012-07-25 18:56:13 -070027#include <ui/DisplayInfo.h>
Mathias Agopian076b1cc2009-04-10 14:24:30 -070028#include <ui/PixelFormat.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080029
Mathias Agopiane3c697f2013-02-14 17:11:02 -080030#include <gui/Surface.h>
Jamie Gennis1a4d8832012-08-02 20:11:05 -070031
Mathias Agopian076b1cc2009-04-10 14:24:30 -070032#include <hardware/gralloc.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080033
Jesse Hall99c7dbb2013-03-14 14:29:29 -070034#include "DisplayHardware/DisplaySurface.h"
Mathias Agopian1b031492012-06-20 17:51:20 -070035#include "DisplayHardware/HWComposer.h"
Mathias Agopian875d8e12013-06-07 15:35:48 -070036#include "RenderEngine/RenderEngine.h"
Mathias Agopian1b031492012-06-20 17:51:20 -070037
Mathias Agopianda8d0a52012-09-04 15:05:38 -070038#include "clz.h"
Mathias Agopian0f2f5ff2012-07-31 23:09:07 -070039#include "DisplayDevice.h"
Mathias Agopianc7d14e22011-08-01 16:32:21 -070040#include "SurfaceFlinger.h"
Mathias Agopian13127d82013-03-05 17:47:11 -080041#include "Layer.h"
Mathias Agopian1f7bec62010-06-25 18:02:21 -070042
Mathias Agopiana4912602012-07-12 14:25:33 -070043// ----------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080044using namespace android;
Mathias Agopiana4912602012-07-12 14:25:33 -070045// ----------------------------------------------------------------------------
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080046
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080047/*
48 * Initialize the display to the specified values.
49 *
50 */
51
Mathias Agopian0f2f5ff2012-07-31 23:09:07 -070052DisplayDevice::DisplayDevice(
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080053 const sp<SurfaceFlinger>& flinger,
Jamie Gennisdd3cb842012-10-19 18:19:11 -070054 DisplayType type,
Jesse Hallffe1f192013-03-22 15:13:48 -070055 int32_t hwcId,
Jesse Hall19e87292013-12-23 21:02:15 -080056 int format,
Jamie Gennisdd3cb842012-10-19 18:19:11 -070057 bool isSecure,
58 const wp<IBinder>& displayToken,
Jesse Hall99c7dbb2013-03-14 14:29:29 -070059 const sp<DisplaySurface>& displaySurface,
Mathias Agopiandb89edc2013-08-02 01:40:18 -070060 const sp<IGraphicBufferProducer>& producer,
Mathias Agopiana4912602012-07-12 14:25:33 -070061 EGLConfig config)
Jesse Hallb7a05492014-08-14 15:45:06 -070062 : lastCompositionHadVisibleLayers(false),
63 mFlinger(flinger),
Jesse Hallffe1f192013-03-22 15:13:48 -070064 mType(type), mHwcDisplayId(hwcId),
Chih-Wei Huang27e25622013-01-07 17:33:56 +080065 mDisplayToken(displayToken),
Jesse Hall99c7dbb2013-03-14 14:29:29 -070066 mDisplaySurface(displaySurface),
Mathias Agopian92a979a2012-08-02 18:32:23 -070067 mDisplay(EGL_NO_DISPLAY),
68 mSurface(EGL_NO_SURFACE),
Mathias Agopian92a979a2012-08-02 18:32:23 -070069 mDisplayWidth(), mDisplayHeight(), mFormat(),
70 mFlags(),
71 mPageFlipCount(),
Jamie Gennisdd3cb842012-10-19 18:19:11 -070072 mIsSecure(isSecure),
Mathias Agopian92a979a2012-08-02 18:32:23 -070073 mSecureLayerVisible(false),
74 mScreenAcquired(false),
Jesse Hall01e29052013-02-19 16:13:35 -080075 mLayerStack(NO_LAYER_STACK),
Mathias Agopianda8d0a52012-09-04 15:05:38 -070076 mOrientation()
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080077{
Jesse Hall83cafff2013-09-16 15:24:53 -070078 mNativeWindow = new Surface(producer, false);
Jesse Hallffe1f192013-03-22 15:13:48 -070079 ANativeWindow* const window = mNativeWindow.get();
80
Jesse Hallf460f552013-08-06 17:08:53 -070081 // 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
Jesse Hallffe1f192013-03-22 15:13:48 -070091 /*
92 * Create our display's surface
93 */
94
95 EGLSurface surface;
96 EGLint w, h;
97 EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
Jesse Hall19e87292013-12-23 21:02:15 -080098 if (config == EGL_NO_CONFIG) {
99 config = RenderEngine::chooseEglConfig(display, format);
100 }
Jesse Hallffe1f192013-03-22 15:13:48 -0700101 surface = eglCreateWindowSurface(display, config, window, NULL);
102 eglQuerySurface(display, surface, EGL_WIDTH, &mDisplayWidth);
103 eglQuerySurface(display, surface, EGL_HEIGHT, &mDisplayHeight);
104
105 mDisplay = display;
106 mSurface = surface;
107 mFormat = format;
108 mPageFlipCount = 0;
109 mViewport.makeInvalid();
110 mFrame.makeInvalid();
111
112 // virtual displays are always considered enabled
113 mScreenAcquired = (mType >= DisplayDevice::DISPLAY_VIRTUAL);
114
115 // Name the display. The name will be replaced shortly if the display
116 // was created with createDisplay().
117 switch (mType) {
118 case DISPLAY_PRIMARY:
119 mDisplayName = "Built-in Screen";
120 break;
121 case DISPLAY_EXTERNAL:
122 mDisplayName = "HDMI Screen";
123 break;
124 default:
125 mDisplayName = "Virtual Screen"; // e.g. Overlay #n
126 break;
127 }
128
129 // initialize the display orientation transform.
130 setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800131}
132
Mathias Agopian0f2f5ff2012-07-31 23:09:07 -0700133DisplayDevice::~DisplayDevice() {
Mathias Agopian92a979a2012-08-02 18:32:23 -0700134 if (mSurface != EGL_NO_SURFACE) {
135 eglDestroySurface(mDisplay, mSurface);
136 mSurface = EGL_NO_SURFACE;
137 }
138}
139
Jesse Hall02d86562013-03-25 14:43:23 -0700140void DisplayDevice::disconnect(HWComposer& hwc) {
141 if (mHwcDisplayId >= 0) {
142 hwc.disconnectDisplay(mHwcDisplayId);
143 if (mHwcDisplayId >= DISPLAY_VIRTUAL)
144 hwc.freeDisplayId(mHwcDisplayId);
145 mHwcDisplayId = -1;
146 }
147}
148
Mathias Agopian92a979a2012-08-02 18:32:23 -0700149bool DisplayDevice::isValid() const {
150 return mFlinger != NULL;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800151}
152
Mathias Agopian0f2f5ff2012-07-31 23:09:07 -0700153int DisplayDevice::getWidth() const {
Mathias Agopiana4912602012-07-12 14:25:33 -0700154 return mDisplayWidth;
155}
156
Mathias Agopian0f2f5ff2012-07-31 23:09:07 -0700157int DisplayDevice::getHeight() const {
Mathias Agopiana4912602012-07-12 14:25:33 -0700158 return mDisplayHeight;
159}
160
Mathias Agopian0f2f5ff2012-07-31 23:09:07 -0700161PixelFormat DisplayDevice::getFormat() const {
Mathias Agopiana4912602012-07-12 14:25:33 -0700162 return mFormat;
163}
164
Mathias Agopian0f2f5ff2012-07-31 23:09:07 -0700165EGLSurface DisplayDevice::getEGLSurface() const {
Mathias Agopiana4912602012-07-12 14:25:33 -0700166 return mSurface;
167}
168
Mathias Agopian9e2463e2012-09-21 18:26:16 -0700169void DisplayDevice::setDisplayName(const String8& displayName) {
170 if (!displayName.isEmpty()) {
171 // never override the name with an empty name
172 mDisplayName = displayName;
173 }
174}
175
Mathias Agopian0f2f5ff2012-07-31 23:09:07 -0700176uint32_t DisplayDevice::getPageFlipCount() const {
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700177 return mPageFlipCount;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800178}
179
Mathias Agopian0f2f5ff2012-07-31 23:09:07 -0700180status_t DisplayDevice::compositionComplete() const {
Jesse Hall99c7dbb2013-03-14 14:29:29 -0700181 return mDisplaySurface->compositionComplete();
Mathias Agopian74faca22009-09-17 16:18:16 -0700182}
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800183
Mathias Agopian0f2f5ff2012-07-31 23:09:07 -0700184void DisplayDevice::flip(const Region& dirty) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800185{
Mathias Agopian875d8e12013-06-07 15:35:48 -0700186 mFlinger->getRenderEngine().checkErrors();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800187
188 EGLDisplay dpy = mDisplay;
189 EGLSurface surface = mSurface;
190
Jesse Hall01e29052013-02-19 16:13:35 -0800191#ifdef EGL_ANDROID_swap_rectangle
Mathias Agopiandf3ca302009-05-04 19:29:25 -0700192 if (mFlags & SWAP_RECTANGLE) {
Mathias Agopianb8a55602009-06-26 19:06:36 -0700193 const Region newDirty(dirty.intersect(bounds()));
194 const Rect b(newDirty.getBounds());
Mathias Agopiandf3ca302009-05-04 19:29:25 -0700195 eglSetSwapRectangleANDROID(dpy, surface,
196 b.left, b.top, b.width(), b.height());
Jesse Hall01e29052013-02-19 16:13:35 -0800197 }
Mathias Agopian5e78e092009-06-11 17:19:54 -0700198#endif
Mathias Agopiand8707032012-09-18 01:21:55 -0700199
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700200 mPageFlipCount++;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800201}
202
Dan Stozaf3c07d42014-02-04 16:22:36 -0800203status_t DisplayDevice::beginFrame(bool mustRecompose) const {
204 return mDisplaySurface->beginFrame(mustRecompose);
Jesse Hall028dc8f2013-08-20 16:35:32 -0700205}
206
Jesse Hall38efe862013-04-06 23:12:29 -0700207status_t DisplayDevice::prepareFrame(const HWComposer& hwc) const {
208 DisplaySurface::CompositionType compositionType;
209 bool haveGles = hwc.hasGlesComposition(mHwcDisplayId);
210 bool haveHwc = hwc.hasHwcComposition(mHwcDisplayId);
211 if (haveGles && haveHwc) {
212 compositionType = DisplaySurface::COMPOSITION_MIXED;
213 } else if (haveGles) {
214 compositionType = DisplaySurface::COMPOSITION_GLES;
215 } else if (haveHwc) {
216 compositionType = DisplaySurface::COMPOSITION_HWC;
217 } else {
218 // Nothing to do -- when turning the screen off we get a frame like
219 // this. Call it a HWC frame since we won't be doing any GLES work but
220 // will do a prepare/set cycle.
221 compositionType = DisplaySurface::COMPOSITION_HWC;
222 }
223 return mDisplaySurface->prepareFrame(compositionType);
224}
225
Mathias Agopianda27af92012-09-13 18:17:13 -0700226void DisplayDevice::swapBuffers(HWComposer& hwc) const {
Andy McFadden22a99f02013-08-20 16:04:47 -0700227 // We need to call eglSwapBuffers() if:
228 // (1) we don't have a hardware composer, or
229 // (2) we did GLES composition this frame, and either
230 // (a) we have framebuffer target support (not present on legacy
231 // devices, where HWComposer::commit() handles things); or
232 // (b) this is a virtual display
Jesse Hall99c7dbb2013-03-14 14:29:29 -0700233 if (hwc.initCheck() != NO_ERROR ||
234 (hwc.hasGlesComposition(mHwcDisplayId) &&
Andy McFadden22a99f02013-08-20 16:04:47 -0700235 (hwc.supportsFramebufferTarget() || mType >= DISPLAY_VIRTUAL))) {
Jesse Hall99c7dbb2013-03-14 14:29:29 -0700236 EGLBoolean success = eglSwapBuffers(mDisplay, mSurface);
237 if (!success) {
238 EGLint error = eglGetError();
239 if (error == EGL_CONTEXT_LOST ||
240 mType == DisplayDevice::DISPLAY_PRIMARY) {
241 LOG_ALWAYS_FATAL("eglSwapBuffers(%p, %p) failed with 0x%08x",
242 mDisplay, mSurface, error);
243 } else {
244 ALOGE("eglSwapBuffers(%p, %p) failed with 0x%08x",
245 mDisplay, mSurface, error);
Mathias Agopianda27af92012-09-13 18:17:13 -0700246 }
247 }
248 }
Mathias Agopian52e21482012-09-24 18:07:21 -0700249
Jesse Hall99c7dbb2013-03-14 14:29:29 -0700250 status_t result = mDisplaySurface->advanceFrame();
251 if (result != NO_ERROR) {
252 ALOGE("[%s] failed pushing new frame to HWC: %d",
253 mDisplayName.string(), result);
Mathias Agopian32341382012-09-25 19:16:28 -0700254 }
Mathias Agopianda27af92012-09-13 18:17:13 -0700255}
256
257void DisplayDevice::onSwapBuffersCompleted(HWComposer& hwc) const {
258 if (hwc.initCheck() == NO_ERROR) {
Jesse Hall851cfe82013-03-20 13:44:00 -0700259 mDisplaySurface->onFrameCommitted();
Mathias Agopianda27af92012-09-13 18:17:13 -0700260 }
261}
262
Mathias Agopian0f2f5ff2012-07-31 23:09:07 -0700263uint32_t DisplayDevice::getFlags() const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800264{
265 return mFlags;
266}
267
Mathias Agopian875d8e12013-06-07 15:35:48 -0700268EGLBoolean DisplayDevice::makeCurrent(EGLDisplay dpy, EGLContext ctx) const {
Mathias Agopianda8d0a52012-09-04 15:05:38 -0700269 EGLBoolean result = EGL_TRUE;
Mathias Agopian52bbb1a2012-07-31 19:01:53 -0700270 EGLSurface sur = eglGetCurrentSurface(EGL_DRAW);
Mathias Agopian875d8e12013-06-07 15:35:48 -0700271 if (sur != mSurface) {
272 result = eglMakeCurrent(dpy, mSurface, mSurface, ctx);
Mathias Agopianda8d0a52012-09-04 15:05:38 -0700273 if (result == EGL_TRUE) {
Jesse Hallf460f552013-08-06 17:08:53 -0700274 if (mType >= DisplayDevice::DISPLAY_VIRTUAL)
275 eglSwapInterval(dpy, 0);
Mathias Agopianda8d0a52012-09-04 15:05:38 -0700276 }
Mathias Agopian52bbb1a2012-07-31 19:01:53 -0700277 }
Mathias Agopian931bda12013-08-28 18:11:46 -0700278 setViewportAndProjection();
Mathias Agopianda8d0a52012-09-04 15:05:38 -0700279 return result;
Mathias Agopian52bbb1a2012-07-31 19:01:53 -0700280}
281
Mathias Agopian875d8e12013-06-07 15:35:48 -0700282void DisplayDevice::setViewportAndProjection() const {
283 size_t w = mDisplayWidth;
284 size_t h = mDisplayHeight;
Mathias Agopian3f844832013-08-07 21:24:32 -0700285 mFlinger->getRenderEngine().setViewportAndProjection(w, h, w, h, false);
Mathias Agopianbae92d02012-09-28 01:00:47 -0700286}
287
Mathias Agopian1b031492012-06-20 17:51:20 -0700288// ----------------------------------------------------------------------------
289
Mathias Agopian13127d82013-03-05 17:47:11 -0800290void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers) {
Mathias Agopian3b1d2b62012-07-11 13:48:17 -0700291 mVisibleLayersSortedByZ = layers;
Mathias Agopianef7b9c72012-08-10 15:22:19 -0700292 mSecureLayerVisible = false;
Mathias Agopian3b1d2b62012-07-11 13:48:17 -0700293 size_t count = layers.size();
294 for (size_t i=0 ; i<count ; i++) {
Mathias Agopian13127d82013-03-05 17:47:11 -0800295 const sp<Layer>& layer(layers[i]);
Mathias Agopianf5f714a2013-02-26 16:54:05 -0800296 if (layer->isSecure()) {
Mathias Agopian3b1d2b62012-07-11 13:48:17 -0700297 mSecureLayerVisible = true;
298 }
299 }
300}
301
Mathias Agopian13127d82013-03-05 17:47:11 -0800302const Vector< sp<Layer> >& DisplayDevice::getVisibleLayersSortedByZ() const {
Mathias Agopian3b1d2b62012-07-11 13:48:17 -0700303 return mVisibleLayersSortedByZ;
304}
305
Mathias Agopian0f2f5ff2012-07-31 23:09:07 -0700306bool DisplayDevice::getSecureLayerVisible() const {
Mathias Agopian3b1d2b62012-07-11 13:48:17 -0700307 return mSecureLayerVisible;
308}
309
Mathias Agopiancd60f992012-08-16 16:28:27 -0700310Region DisplayDevice::getDirtyRegion(bool repaintEverything) const {
311 Region dirty;
Mathias Agopiancd60f992012-08-16 16:28:27 -0700312 if (repaintEverything) {
313 dirty.set(getBounds());
314 } else {
Mathias Agopianda8d0a52012-09-04 15:05:38 -0700315 const Transform& planeTransform(mGlobalTransform);
Mathias Agopiancd60f992012-08-16 16:28:27 -0700316 dirty = planeTransform.transform(this->dirtyRegion);
317 dirty.andSelf(getBounds());
318 }
319 return dirty;
320}
321
Mathias Agopian3b1d2b62012-07-11 13:48:17 -0700322// ----------------------------------------------------------------------------
323
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700324bool DisplayDevice::canDraw() const {
325 return mScreenAcquired;
326}
327
328void DisplayDevice::releaseScreen() const {
329 mScreenAcquired = false;
330}
331
332void DisplayDevice::acquireScreen() const {
333 mScreenAcquired = true;
334}
335
336bool DisplayDevice::isScreenAcquired() const {
337 return mScreenAcquired;
338}
339
340// ----------------------------------------------------------------------------
341
Mathias Agopian28947d72012-08-08 18:51:15 -0700342void DisplayDevice::setLayerStack(uint32_t stack) {
343 mLayerStack = stack;
344 dirtyRegion.set(bounds());
345}
346
347// ----------------------------------------------------------------------------
348
Mathias Agopianc1c05de2013-09-17 23:45:22 -0700349uint32_t DisplayDevice::getOrientationTransform() const {
350 uint32_t transform = 0;
351 switch (mOrientation) {
352 case DisplayState::eOrientationDefault:
353 transform = Transform::ROT_0;
354 break;
355 case DisplayState::eOrientation90:
356 transform = Transform::ROT_90;
357 break;
358 case DisplayState::eOrientation180:
359 transform = Transform::ROT_180;
360 break;
361 case DisplayState::eOrientation270:
362 transform = Transform::ROT_270;
363 break;
364 }
365 return transform;
366}
367
Mathias Agopian0f2f5ff2012-07-31 23:09:07 -0700368status_t DisplayDevice::orientationToTransfrom(
Mathias Agopian1b031492012-06-20 17:51:20 -0700369 int orientation, int w, int h, Transform* tr)
370{
371 uint32_t flags = 0;
372 switch (orientation) {
Mathias Agopian3165cc22012-08-08 19:42:09 -0700373 case DisplayState::eOrientationDefault:
Mathias Agopian1b031492012-06-20 17:51:20 -0700374 flags = Transform::ROT_0;
375 break;
Mathias Agopian3165cc22012-08-08 19:42:09 -0700376 case DisplayState::eOrientation90:
Mathias Agopian1b031492012-06-20 17:51:20 -0700377 flags = Transform::ROT_90;
378 break;
Mathias Agopian3165cc22012-08-08 19:42:09 -0700379 case DisplayState::eOrientation180:
Mathias Agopian1b031492012-06-20 17:51:20 -0700380 flags = Transform::ROT_180;
381 break;
Mathias Agopian3165cc22012-08-08 19:42:09 -0700382 case DisplayState::eOrientation270:
Mathias Agopian1b031492012-06-20 17:51:20 -0700383 flags = Transform::ROT_270;
384 break;
385 default:
386 return BAD_VALUE;
387 }
388 tr->set(flags, w, h);
389 return NO_ERROR;
390}
391
Mathias Agopian00e8c7a2012-09-04 19:30:46 -0700392void DisplayDevice::setProjection(int orientation,
Mathias Agopianf5f714a2013-02-26 16:54:05 -0800393 const Rect& newViewport, const Rect& newFrame) {
394 Rect viewport(newViewport);
395 Rect frame(newFrame);
396
397 const int w = mDisplayWidth;
398 const int h = mDisplayHeight;
399
400 Transform R;
401 DisplayDevice::orientationToTransfrom(orientation, w, h, &R);
402
403 if (!frame.isValid()) {
404 // the destination frame can be invalid if it has never been set,
405 // in that case we assume the whole display frame.
406 frame = Rect(w, h);
407 }
408
409 if (viewport.isEmpty()) {
410 // viewport can be invalid if it has never been set, in that case
411 // we assume the whole display size.
412 // it's also invalid to have an empty viewport, so we handle that
413 // case in the same way.
414 viewport = Rect(w, h);
415 if (R.getOrientation() & Transform::ROT_90) {
416 // viewport is always specified in the logical orientation
417 // of the display (ie: post-rotation).
418 swap(viewport.right, viewport.bottom);
419 }
420 }
421
422 dirtyRegion.set(getBounds());
423
424 Transform TL, TP, S;
425 float src_width = viewport.width();
426 float src_height = viewport.height();
427 float dst_width = frame.width();
428 float dst_height = frame.height();
429 if (src_width != dst_width || src_height != dst_height) {
430 float sx = dst_width / src_width;
431 float sy = dst_height / src_height;
432 S.set(sx, 0, 0, sy);
433 }
434
435 float src_x = viewport.left;
436 float src_y = viewport.top;
437 float dst_x = frame.left;
438 float dst_y = frame.top;
439 TL.set(-src_x, -src_y);
440 TP.set(dst_x, dst_y);
441
442 // The viewport and frame are both in the logical orientation.
443 // Apply the logical translation, scale to physical size, apply the
444 // physical translation and finally rotate to the physical orientation.
445 mGlobalTransform = R * TP * S * TL;
446
447 const uint8_t type = mGlobalTransform.getType();
448 mNeedsFiltering = (!mGlobalTransform.preserveRects() ||
449 (type >= Transform::SCALE));
450
451 mScissor = mGlobalTransform.transform(viewport);
452 if (mScissor.isEmpty()) {
Mathias Agopian6c7f25a2013-05-09 20:37:10 -0700453 mScissor = getBounds();
Mathias Agopianf5f714a2013-02-26 16:54:05 -0800454 }
455
Mathias Agopianda8d0a52012-09-04 15:05:38 -0700456 mOrientation = orientation;
Mathias Agopian00e8c7a2012-09-04 19:30:46 -0700457 mViewport = viewport;
458 mFrame = frame;
Mathias Agopian1b031492012-06-20 17:51:20 -0700459}
Mathias Agopian1d12d8a2012-09-18 01:38:00 -0700460
Mathias Agopian74d211a2013-04-22 16:55:35 +0200461void DisplayDevice::dump(String8& result) const {
Mathias Agopian1d12d8a2012-09-18 01:38:00 -0700462 const Transform& tr(mGlobalTransform);
Mathias Agopian74d211a2013-04-22 16:55:35 +0200463 result.appendFormat(
Mathias Agopian1d12d8a2012-09-18 01:38:00 -0700464 "+ DisplayDevice: %s\n"
Jesse Hall02d86562013-03-25 14:43:23 -0700465 " type=%x, hwcId=%d, layerStack=%u, (%4dx%4d), ANativeWindow=%p, orient=%2d (type=%08x), "
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700466 "flips=%u, isSecure=%d, secureVis=%d, acquired=%d, numLayers=%u\n"
Mathias Agopian766dc492012-10-30 18:08:06 -0700467 " v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d],"
Mathias Agopian1d12d8a2012-09-18 01:38:00 -0700468 "transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n",
Jesse Hall02d86562013-03-25 14:43:23 -0700469 mDisplayName.string(), mType, mHwcDisplayId,
Mathias Agopian1d12d8a2012-09-18 01:38:00 -0700470 mLayerStack, mDisplayWidth, mDisplayHeight, mNativeWindow.get(),
471 mOrientation, tr.getType(), getPageFlipCount(),
Jamie Gennisdd3cb842012-10-19 18:19:11 -0700472 mIsSecure, mSecureLayerVisible, mScreenAcquired, mVisibleLayersSortedByZ.size(),
Mathias Agopian1d12d8a2012-09-18 01:38:00 -0700473 mViewport.left, mViewport.top, mViewport.right, mViewport.bottom,
474 mFrame.left, mFrame.top, mFrame.right, mFrame.bottom,
Mathias Agopian766dc492012-10-30 18:08:06 -0700475 mScissor.left, mScissor.top, mScissor.right, mScissor.bottom,
Mathias Agopian1d12d8a2012-09-18 01:38:00 -0700476 tr[0][0], tr[1][0], tr[2][0],
477 tr[0][1], tr[1][1], tr[2][1],
478 tr[0][2], tr[1][2], tr[2][2]);
479
Jesse Hall99c7dbb2013-03-14 14:29:29 -0700480 String8 surfaceDump;
481 mDisplaySurface->dump(surfaceDump);
482 result.append(surfaceDump);
Mathias Agopian1d12d8a2012-09-18 01:38:00 -0700483}