• 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 // #define LOG_NDEBUG 0
18 #undef LOG_TAG
19 #define LOG_TAG "DisplayDevice"
20 
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <math.h>
25 
26 #include <cutils/properties.h>
27 
28 #include <utils/RefBase.h>
29 #include <utils/Log.h>
30 
31 #include <ui/DisplayInfo.h>
32 #include <ui/PixelFormat.h>
33 
34 #include <gui/Surface.h>
35 
36 #include <hardware/gralloc.h>
37 
38 #include "DisplayHardware/DisplaySurface.h"
39 #include "DisplayHardware/HWComposer.h"
40 #ifdef USE_HWC2
41 #include "DisplayHardware/HWC2.h"
42 #endif
43 #include "RenderEngine/RenderEngine.h"
44 
45 #include "clz.h"
46 #include "DisplayDevice.h"
47 #include "SurfaceFlinger.h"
48 #include "Layer.h"
49 
50 #include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
51 #include <configstore/Utils.h>
52 
53 // ----------------------------------------------------------------------------
54 using namespace android;
55 // ----------------------------------------------------------------------------
56 
57 #ifdef EGL_ANDROID_swap_rectangle
58 static constexpr bool kEGLAndroidSwapRectangle = true;
59 #else
60 static constexpr bool kEGLAndroidSwapRectangle = false;
61 #endif
62 
63 // retrieve triple buffer setting from configstore
64 using namespace android::hardware::configstore;
65 using namespace android::hardware::configstore::V1_0;
66 
67 static bool useTripleFramebuffer = getInt64< ISurfaceFlingerConfigs,
68         &ISurfaceFlingerConfigs::maxFrameBufferAcquiredBuffers>(2) == 3;
69 
70 #if !defined(EGL_EGLEXT_PROTOTYPES) || !defined(EGL_ANDROID_swap_rectangle)
71 // Dummy implementation in case it is missing.
eglSetSwapRectangleANDROID(EGLDisplay,EGLSurface,EGLint,EGLint,EGLint,EGLint)72 inline void eglSetSwapRectangleANDROID (EGLDisplay, EGLSurface, EGLint, EGLint, EGLint, EGLint) {
73 }
74 #endif
75 
76 /*
77  * Initialize the display to the specified values.
78  *
79  */
80 
81 uint32_t DisplayDevice::sPrimaryDisplayOrientation = 0;
82 
83 // clang-format off
DisplayDevice(const sp<SurfaceFlinger> & flinger,DisplayType type,int32_t hwcId,int format,bool isSecure,const wp<IBinder> & displayToken,const sp<DisplaySurface> & displaySurface,const sp<IGraphicBufferProducer> & producer,EGLConfig config,bool supportWideColor)84 DisplayDevice::DisplayDevice(
85         const sp<SurfaceFlinger>& flinger,
86         DisplayType type,
87         int32_t hwcId,
88 #ifndef USE_HWC2
89         int format,
90 #endif
91         bool isSecure,
92         const wp<IBinder>& displayToken,
93         const sp<DisplaySurface>& displaySurface,
94         const sp<IGraphicBufferProducer>& producer,
95         EGLConfig config,
96         bool supportWideColor)
97     : lastCompositionHadVisibleLayers(false),
98       mFlinger(flinger),
99       mType(type),
100       mHwcDisplayId(hwcId),
101       mDisplayToken(displayToken),
102       mDisplaySurface(displaySurface),
103       mDisplay(EGL_NO_DISPLAY),
104       mSurface(EGL_NO_SURFACE),
105       mDisplayWidth(),
106       mDisplayHeight(),
107 #ifndef USE_HWC2
108       mFormat(),
109 #endif
110       mFlags(),
111       mPageFlipCount(),
112       mIsSecure(isSecure),
113       mLayerStack(NO_LAYER_STACK),
114       mOrientation(),
115       mPowerMode(HWC_POWER_MODE_OFF),
116       mActiveConfig(0)
117 {
118     // clang-format on
119     Surface* surface;
120     mNativeWindow = surface = new Surface(producer, false);
121     ANativeWindow* const window = mNativeWindow.get();
122 
123 #ifdef USE_HWC2
124     mActiveColorMode = static_cast<android_color_mode_t>(-1);
125     mDisplayHasWideColor = supportWideColor;
126 #else
127     (void) supportWideColor;
128 #endif
129     /*
130      * Create our display's surface
131      */
132 
133     EGLSurface eglSurface;
134     EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
135     if (config == EGL_NO_CONFIG) {
136 #ifdef USE_HWC2
137         config = RenderEngine::chooseEglConfig(display, PIXEL_FORMAT_RGBA_8888);
138 #else
139         config = RenderEngine::chooseEglConfig(display, format);
140 #endif
141     }
142     eglSurface = eglCreateWindowSurface(display, config, window, NULL);
143     eglQuerySurface(display, eglSurface, EGL_WIDTH,  &mDisplayWidth);
144     eglQuerySurface(display, eglSurface, EGL_HEIGHT, &mDisplayHeight);
145 
146     // Make sure that composition can never be stalled by a virtual display
147     // consumer that isn't processing buffers fast enough. We have to do this
148     // in two places:
149     // * Here, in case the display is composed entirely by HWC.
150     // * In makeCurrent(), using eglSwapInterval. Some EGL drivers set the
151     //   window's swap interval in eglMakeCurrent, so they'll override the
152     //   interval we set here.
153     if (mType >= DisplayDevice::DISPLAY_VIRTUAL)
154         window->setSwapInterval(window, 0);
155 
156     mConfig = config;
157     mDisplay = display;
158     mSurface = eglSurface;
159 #ifndef USE_HWC2
160     mFormat = format;
161 #endif
162     mPageFlipCount = 0;
163     mViewport.makeInvalid();
164     mFrame.makeInvalid();
165 
166     // virtual displays are always considered enabled
167     mPowerMode = (mType >= DisplayDevice::DISPLAY_VIRTUAL) ?
168                   HWC_POWER_MODE_NORMAL : HWC_POWER_MODE_OFF;
169 
170     // Name the display.  The name will be replaced shortly if the display
171     // was created with createDisplay().
172     switch (mType) {
173         case DISPLAY_PRIMARY:
174             mDisplayName = "Built-in Screen";
175             break;
176         case DISPLAY_EXTERNAL:
177             mDisplayName = "HDMI Screen";
178             break;
179         default:
180             mDisplayName = "Virtual Screen";    // e.g. Overlay #n
181             break;
182     }
183 
184     // initialize the display orientation transform.
185     setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);
186 
187     if (useTripleFramebuffer) {
188         surface->allocateBuffers();
189     }
190 }
191 
~DisplayDevice()192 DisplayDevice::~DisplayDevice() {
193     if (mSurface != EGL_NO_SURFACE) {
194         eglDestroySurface(mDisplay, mSurface);
195         mSurface = EGL_NO_SURFACE;
196     }
197 }
198 
disconnect(HWComposer & hwc)199 void DisplayDevice::disconnect(HWComposer& hwc) {
200     if (mHwcDisplayId >= 0) {
201         hwc.disconnectDisplay(mHwcDisplayId);
202 #ifndef USE_HWC2
203         if (mHwcDisplayId >= DISPLAY_VIRTUAL)
204             hwc.freeDisplayId(mHwcDisplayId);
205 #endif
206         mHwcDisplayId = -1;
207     }
208 }
209 
isValid() const210 bool DisplayDevice::isValid() const {
211     return mFlinger != NULL;
212 }
213 
getWidth() const214 int DisplayDevice::getWidth() const {
215     return mDisplayWidth;
216 }
217 
getHeight() const218 int DisplayDevice::getHeight() const {
219     return mDisplayHeight;
220 }
221 
222 #ifndef USE_HWC2
getFormat() const223 PixelFormat DisplayDevice::getFormat() const {
224     return mFormat;
225 }
226 #endif
227 
getEGLSurface() const228 EGLSurface DisplayDevice::getEGLSurface() const {
229     return mSurface;
230 }
231 
setDisplayName(const String8 & displayName)232 void DisplayDevice::setDisplayName(const String8& displayName) {
233     if (!displayName.isEmpty()) {
234         // never override the name with an empty name
235         mDisplayName = displayName;
236     }
237 }
238 
getPageFlipCount() const239 uint32_t DisplayDevice::getPageFlipCount() const {
240     return mPageFlipCount;
241 }
242 
243 #ifndef USE_HWC2
compositionComplete() const244 status_t DisplayDevice::compositionComplete() const {
245     return mDisplaySurface->compositionComplete();
246 }
247 #endif
248 
flip(const Region & dirty) const249 void DisplayDevice::flip(const Region& dirty) const
250 {
251     mFlinger->getRenderEngine().checkErrors();
252 
253     if (kEGLAndroidSwapRectangle) {
254         if (mFlags & SWAP_RECTANGLE) {
255             const Region newDirty(dirty.intersect(bounds()));
256             const Rect b(newDirty.getBounds());
257             eglSetSwapRectangleANDROID(mDisplay, mSurface,
258                     b.left, b.top, b.width(), b.height());
259         }
260     }
261 
262     mPageFlipCount++;
263 }
264 
beginFrame(bool mustRecompose) const265 status_t DisplayDevice::beginFrame(bool mustRecompose) const {
266     return mDisplaySurface->beginFrame(mustRecompose);
267 }
268 
269 #ifdef USE_HWC2
prepareFrame(HWComposer & hwc)270 status_t DisplayDevice::prepareFrame(HWComposer& hwc) {
271     status_t error = hwc.prepare(*this);
272     if (error != NO_ERROR) {
273         return error;
274     }
275 
276     DisplaySurface::CompositionType compositionType;
277     bool hasClient = hwc.hasClientComposition(mHwcDisplayId);
278     bool hasDevice = hwc.hasDeviceComposition(mHwcDisplayId);
279     if (hasClient && hasDevice) {
280         compositionType = DisplaySurface::COMPOSITION_MIXED;
281     } else if (hasClient) {
282         compositionType = DisplaySurface::COMPOSITION_GLES;
283     } else if (hasDevice) {
284         compositionType = DisplaySurface::COMPOSITION_HWC;
285     } else {
286         // Nothing to do -- when turning the screen off we get a frame like
287         // this. Call it a HWC frame since we won't be doing any GLES work but
288         // will do a prepare/set cycle.
289         compositionType = DisplaySurface::COMPOSITION_HWC;
290     }
291     return mDisplaySurface->prepareFrame(compositionType);
292 }
293 #else
prepareFrame(const HWComposer & hwc) const294 status_t DisplayDevice::prepareFrame(const HWComposer& hwc) const {
295     DisplaySurface::CompositionType compositionType;
296     bool haveGles = hwc.hasGlesComposition(mHwcDisplayId);
297     bool haveHwc = hwc.hasHwcComposition(mHwcDisplayId);
298     if (haveGles && haveHwc) {
299         compositionType = DisplaySurface::COMPOSITION_MIXED;
300     } else if (haveGles) {
301         compositionType = DisplaySurface::COMPOSITION_GLES;
302     } else if (haveHwc) {
303         compositionType = DisplaySurface::COMPOSITION_HWC;
304     } else {
305         // Nothing to do -- when turning the screen off we get a frame like
306         // this. Call it a HWC frame since we won't be doing any GLES work but
307         // will do a prepare/set cycle.
308         compositionType = DisplaySurface::COMPOSITION_HWC;
309     }
310     return mDisplaySurface->prepareFrame(compositionType);
311 }
312 #endif
313 
swapBuffers(HWComposer & hwc) const314 void DisplayDevice::swapBuffers(HWComposer& hwc) const {
315 #ifdef USE_HWC2
316     if (hwc.hasClientComposition(mHwcDisplayId)) {
317 #else
318     // We need to call eglSwapBuffers() if:
319     //  (1) we don't have a hardware composer, or
320     //  (2) we did GLES composition this frame, and either
321     //    (a) we have framebuffer target support (not present on legacy
322     //        devices, where HWComposer::commit() handles things); or
323     //    (b) this is a virtual display
324     if (hwc.initCheck() != NO_ERROR ||
325             (hwc.hasGlesComposition(mHwcDisplayId) &&
326              (hwc.supportsFramebufferTarget() || mType >= DISPLAY_VIRTUAL))) {
327 #endif
328         EGLBoolean success = eglSwapBuffers(mDisplay, mSurface);
329         if (!success) {
330             EGLint error = eglGetError();
331             if (error == EGL_CONTEXT_LOST ||
332                     mType == DisplayDevice::DISPLAY_PRIMARY) {
333                 LOG_ALWAYS_FATAL("eglSwapBuffers(%p, %p) failed with 0x%08x",
334                         mDisplay, mSurface, error);
335             } else {
336                 ALOGE("eglSwapBuffers(%p, %p) failed with 0x%08x",
337                         mDisplay, mSurface, error);
338             }
339         }
340     }
341 
342     status_t result = mDisplaySurface->advanceFrame();
343     if (result != NO_ERROR) {
344         ALOGE("[%s] failed pushing new frame to HWC: %d",
345                 mDisplayName.string(), result);
346     }
347 }
348 
349 #ifdef USE_HWC2
350 void DisplayDevice::onSwapBuffersCompleted() const {
351     mDisplaySurface->onFrameCommitted();
352 }
353 #else
354 void DisplayDevice::onSwapBuffersCompleted(HWComposer& hwc) const {
355     if (hwc.initCheck() == NO_ERROR) {
356         mDisplaySurface->onFrameCommitted();
357     }
358 }
359 #endif
360 
361 uint32_t DisplayDevice::getFlags() const
362 {
363     return mFlags;
364 }
365 
366 EGLBoolean DisplayDevice::makeCurrent(EGLDisplay dpy, EGLContext ctx) const {
367     EGLBoolean result = EGL_TRUE;
368     EGLSurface sur = eglGetCurrentSurface(EGL_DRAW);
369     if (sur != mSurface) {
370         result = eglMakeCurrent(dpy, mSurface, mSurface, ctx);
371         if (result == EGL_TRUE) {
372             if (mType >= DisplayDevice::DISPLAY_VIRTUAL)
373                 eglSwapInterval(dpy, 0);
374         }
375     }
376     setViewportAndProjection();
377     return result;
378 }
379 
380 void DisplayDevice::setViewportAndProjection() const {
381     size_t w = mDisplayWidth;
382     size_t h = mDisplayHeight;
383     Rect sourceCrop(0, 0, w, h);
384     mFlinger->getRenderEngine().setViewportAndProjection(w, h, sourceCrop, h,
385         false, Transform::ROT_0);
386 }
387 
388 const sp<Fence>& DisplayDevice::getClientTargetAcquireFence() const {
389     return mDisplaySurface->getClientTargetAcquireFence();
390 }
391 
392 // ----------------------------------------------------------------------------
393 
394 void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers) {
395     mVisibleLayersSortedByZ = layers;
396 }
397 
398 const Vector< sp<Layer> >& DisplayDevice::getVisibleLayersSortedByZ() const {
399     return mVisibleLayersSortedByZ;
400 }
401 
402 Region DisplayDevice::getDirtyRegion(bool repaintEverything) const {
403     Region dirty;
404     if (repaintEverything) {
405         dirty.set(getBounds());
406     } else {
407         const Transform& planeTransform(mGlobalTransform);
408         dirty = planeTransform.transform(this->dirtyRegion);
409         dirty.andSelf(getBounds());
410     }
411     return dirty;
412 }
413 
414 // ----------------------------------------------------------------------------
415 void DisplayDevice::setPowerMode(int mode) {
416     mPowerMode = mode;
417 }
418 
419 int DisplayDevice::getPowerMode()  const {
420     return mPowerMode;
421 }
422 
423 bool DisplayDevice::isDisplayOn() const {
424     return (mPowerMode != HWC_POWER_MODE_OFF);
425 }
426 
427 // ----------------------------------------------------------------------------
428 void DisplayDevice::setActiveConfig(int mode) {
429     mActiveConfig = mode;
430 }
431 
432 int DisplayDevice::getActiveConfig()  const {
433     return mActiveConfig;
434 }
435 
436 // ----------------------------------------------------------------------------
437 #ifdef USE_HWC2
438 void DisplayDevice::setActiveColorMode(android_color_mode_t mode) {
439     mActiveColorMode = mode;
440 }
441 
442 android_color_mode_t DisplayDevice::getActiveColorMode() const {
443     return mActiveColorMode;
444 }
445 #endif
446 
447 // ----------------------------------------------------------------------------
448 
449 void DisplayDevice::setLayerStack(uint32_t stack) {
450     mLayerStack = stack;
451     dirtyRegion.set(bounds());
452 }
453 
454 // ----------------------------------------------------------------------------
455 
456 uint32_t DisplayDevice::getOrientationTransform() const {
457     uint32_t transform = 0;
458     switch (mOrientation) {
459         case DisplayState::eOrientationDefault:
460             transform = Transform::ROT_0;
461             break;
462         case DisplayState::eOrientation90:
463             transform = Transform::ROT_90;
464             break;
465         case DisplayState::eOrientation180:
466             transform = Transform::ROT_180;
467             break;
468         case DisplayState::eOrientation270:
469             transform = Transform::ROT_270;
470             break;
471     }
472     return transform;
473 }
474 
475 status_t DisplayDevice::orientationToTransfrom(
476         int orientation, int w, int h, Transform* tr)
477 {
478     uint32_t flags = 0;
479     switch (orientation) {
480     case DisplayState::eOrientationDefault:
481         flags = Transform::ROT_0;
482         break;
483     case DisplayState::eOrientation90:
484         flags = Transform::ROT_90;
485         break;
486     case DisplayState::eOrientation180:
487         flags = Transform::ROT_180;
488         break;
489     case DisplayState::eOrientation270:
490         flags = Transform::ROT_270;
491         break;
492     default:
493         return BAD_VALUE;
494     }
495     tr->set(flags, w, h);
496     return NO_ERROR;
497 }
498 
499 void DisplayDevice::setDisplaySize(const int newWidth, const int newHeight) {
500     dirtyRegion.set(getBounds());
501 
502     if (mSurface != EGL_NO_SURFACE) {
503         eglDestroySurface(mDisplay, mSurface);
504         mSurface = EGL_NO_SURFACE;
505     }
506 
507     mDisplaySurface->resizeBuffers(newWidth, newHeight);
508 
509     ANativeWindow* const window = mNativeWindow.get();
510     mSurface = eglCreateWindowSurface(mDisplay, mConfig, window, NULL);
511     eglQuerySurface(mDisplay, mSurface, EGL_WIDTH,  &mDisplayWidth);
512     eglQuerySurface(mDisplay, mSurface, EGL_HEIGHT, &mDisplayHeight);
513 
514     LOG_FATAL_IF(mDisplayWidth != newWidth,
515                 "Unable to set new width to %d", newWidth);
516     LOG_FATAL_IF(mDisplayHeight != newHeight,
517                 "Unable to set new height to %d", newHeight);
518 }
519 
520 void DisplayDevice::setProjection(int orientation,
521         const Rect& newViewport, const Rect& newFrame) {
522     Rect viewport(newViewport);
523     Rect frame(newFrame);
524 
525     const int w = mDisplayWidth;
526     const int h = mDisplayHeight;
527 
528     Transform R;
529     DisplayDevice::orientationToTransfrom(orientation, w, h, &R);
530 
531     if (!frame.isValid()) {
532         // the destination frame can be invalid if it has never been set,
533         // in that case we assume the whole display frame.
534         frame = Rect(w, h);
535     }
536 
537     if (viewport.isEmpty()) {
538         // viewport can be invalid if it has never been set, in that case
539         // we assume the whole display size.
540         // it's also invalid to have an empty viewport, so we handle that
541         // case in the same way.
542         viewport = Rect(w, h);
543         if (R.getOrientation() & Transform::ROT_90) {
544             // viewport is always specified in the logical orientation
545             // of the display (ie: post-rotation).
546             swap(viewport.right, viewport.bottom);
547         }
548     }
549 
550     dirtyRegion.set(getBounds());
551 
552     Transform TL, TP, S;
553     float src_width  = viewport.width();
554     float src_height = viewport.height();
555     float dst_width  = frame.width();
556     float dst_height = frame.height();
557     if (src_width != dst_width || src_height != dst_height) {
558         float sx = dst_width  / src_width;
559         float sy = dst_height / src_height;
560         S.set(sx, 0, 0, sy);
561     }
562 
563     float src_x = viewport.left;
564     float src_y = viewport.top;
565     float dst_x = frame.left;
566     float dst_y = frame.top;
567     TL.set(-src_x, -src_y);
568     TP.set(dst_x, dst_y);
569 
570     // The viewport and frame are both in the logical orientation.
571     // Apply the logical translation, scale to physical size, apply the
572     // physical translation and finally rotate to the physical orientation.
573     mGlobalTransform = R * TP * S * TL;
574 
575     const uint8_t type = mGlobalTransform.getType();
576     mNeedsFiltering = (!mGlobalTransform.preserveRects() ||
577             (type >= Transform::SCALE));
578 
579     mScissor = mGlobalTransform.transform(viewport);
580     if (mScissor.isEmpty()) {
581         mScissor = getBounds();
582     }
583 
584     mOrientation = orientation;
585     if (mType == DisplayType::DISPLAY_PRIMARY) {
586         uint32_t transform = 0;
587         switch (mOrientation) {
588             case DisplayState::eOrientationDefault:
589                 transform = Transform::ROT_0;
590                 break;
591             case DisplayState::eOrientation90:
592                 transform = Transform::ROT_90;
593                 break;
594             case DisplayState::eOrientation180:
595                 transform = Transform::ROT_180;
596                 break;
597             case DisplayState::eOrientation270:
598                 transform = Transform::ROT_270;
599                 break;
600         }
601         sPrimaryDisplayOrientation = transform;
602     }
603     mViewport = viewport;
604     mFrame = frame;
605 }
606 
607 uint32_t DisplayDevice::getPrimaryDisplayOrientationTransform() {
608     return sPrimaryDisplayOrientation;
609 }
610 
611 void DisplayDevice::dump(String8& result) const {
612     const Transform& tr(mGlobalTransform);
613     result.appendFormat(
614         "+ DisplayDevice: %s\n"
615         "   type=%x, hwcId=%d, layerStack=%u, (%4dx%4d), ANativeWindow=%p, orient=%2d (type=%08x), "
616         "flips=%u, isSecure=%d, powerMode=%d, activeConfig=%d, numLayers=%zu\n"
617         "   v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d],"
618         "transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n",
619         mDisplayName.string(), mType, mHwcDisplayId,
620         mLayerStack, mDisplayWidth, mDisplayHeight, mNativeWindow.get(),
621         mOrientation, tr.getType(), getPageFlipCount(),
622         mIsSecure, mPowerMode, mActiveConfig,
623         mVisibleLayersSortedByZ.size(),
624         mViewport.left, mViewport.top, mViewport.right, mViewport.bottom,
625         mFrame.left, mFrame.top, mFrame.right, mFrame.bottom,
626         mScissor.left, mScissor.top, mScissor.right, mScissor.bottom,
627         tr[0][0], tr[1][0], tr[2][0],
628         tr[0][1], tr[1][1], tr[2][1],
629         tr[0][2], tr[1][2], tr[2][2]);
630 
631     String8 surfaceDump;
632     mDisplaySurface->dumpAsString(surfaceDump);
633     result.append(surfaceDump);
634 }
635 
636 std::atomic<int32_t> DisplayDeviceState::nextDisplayId(1);
637 
638 DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type, bool isSecure)
639     : type(type),
640       layerStack(DisplayDevice::NO_LAYER_STACK),
641       orientation(0),
642       width(0),
643       height(0),
644       isSecure(isSecure)
645 {
646     viewport.makeInvalid();
647     frame.makeInvalid();
648 }
649