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 <stdint.h>
20 #include <unistd.h>
21 #include <fcntl.h>
22 #include <errno.h>
23 #include <math.h>
24 #include <limits.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <sys/ioctl.h>
28
29 #include <cutils/log.h>
30 #include <cutils/properties.h>
31
32 #include <binder/IPCThreadState.h>
33 #include <binder/IServiceManager.h>
34 #include <binder/MemoryHeapBase.h>
35
36 #include <utils/String8.h>
37 #include <utils/String16.h>
38 #include <utils/StopWatch.h>
39
40 #include <ui/GraphicBufferAllocator.h>
41 #include <ui/PixelFormat.h>
42 #include <ui/DisplayInfo.h>
43
44 #include <pixelflinger/pixelflinger.h>
45 #include <GLES/gl.h>
46
47 #include "clz.h"
48 #include "Layer.h"
49 #include "LayerBlur.h"
50 #include "LayerBuffer.h"
51 #include "LayerDim.h"
52 #include "SurfaceFlinger.h"
53
54 #include "DisplayHardware/DisplayHardware.h"
55
56 /* ideally AID_GRAPHICS would be in a semi-public header
57 * or there would be a way to map a user/group name to its id
58 */
59 #ifndef AID_GRAPHICS
60 #define AID_GRAPHICS 1003
61 #endif
62
63 #define DISPLAY_COUNT 1
64
65 namespace android {
66
67 // ---------------------------------------------------------------------------
68
instantiate()69 void SurfaceFlinger::instantiate() {
70 defaultServiceManager()->addService(
71 String16("SurfaceFlinger"), new SurfaceFlinger());
72 }
73
shutdown()74 void SurfaceFlinger::shutdown() {
75 // we should unregister here, but not really because
76 // when (if) the service manager goes away, all the services
77 // it has a reference to will leave too.
78 }
79
80 // ---------------------------------------------------------------------------
81
LayerVector(const SurfaceFlinger::LayerVector & rhs)82 SurfaceFlinger::LayerVector::LayerVector(const SurfaceFlinger::LayerVector& rhs)
83 : lookup(rhs.lookup), layers(rhs.layers)
84 {
85 }
86
indexOf(const sp<LayerBase> & key,size_t guess) const87 ssize_t SurfaceFlinger::LayerVector::indexOf(
88 const sp<LayerBase>& key, size_t guess) const
89 {
90 if (guess<size() && lookup.keyAt(guess) == key)
91 return guess;
92 const ssize_t i = lookup.indexOfKey(key);
93 if (i>=0) {
94 const size_t idx = lookup.valueAt(i);
95 LOGE_IF(layers[idx]!=key,
96 "LayerVector[%p]: layers[%d]=%p, key=%p",
97 this, int(idx), layers[idx].get(), key.get());
98 return idx;
99 }
100 return i;
101 }
102
add(const sp<LayerBase> & layer,Vector<sp<LayerBase>>::compar_t cmp)103 ssize_t SurfaceFlinger::LayerVector::add(
104 const sp<LayerBase>& layer,
105 Vector< sp<LayerBase> >::compar_t cmp)
106 {
107 size_t count = layers.size();
108 ssize_t l = 0;
109 ssize_t h = count-1;
110 ssize_t mid;
111 sp<LayerBase> const* a = layers.array();
112 while (l <= h) {
113 mid = l + (h - l)/2;
114 const int c = cmp(a+mid, &layer);
115 if (c == 0) { l = mid; break; }
116 else if (c<0) { l = mid+1; }
117 else { h = mid-1; }
118 }
119 size_t order = l;
120 while (order<count && !cmp(&layer, a+order)) {
121 order++;
122 }
123 count = lookup.size();
124 for (size_t i=0 ; i<count ; i++) {
125 if (lookup.valueAt(i) >= order) {
126 lookup.editValueAt(i)++;
127 }
128 }
129 layers.insertAt(layer, order);
130 lookup.add(layer, order);
131 return order;
132 }
133
remove(const sp<LayerBase> & layer)134 ssize_t SurfaceFlinger::LayerVector::remove(const sp<LayerBase>& layer)
135 {
136 const ssize_t keyIndex = lookup.indexOfKey(layer);
137 if (keyIndex >= 0) {
138 const size_t index = lookup.valueAt(keyIndex);
139 LOGE_IF(layers[index]!=layer,
140 "LayerVector[%p]: layers[%u]=%p, layer=%p",
141 this, int(index), layers[index].get(), layer.get());
142 layers.removeItemsAt(index);
143 lookup.removeItemsAt(keyIndex);
144 const size_t count = lookup.size();
145 for (size_t i=0 ; i<count ; i++) {
146 if (lookup.valueAt(i) >= size_t(index)) {
147 lookup.editValueAt(i)--;
148 }
149 }
150 return index;
151 }
152 return NAME_NOT_FOUND;
153 }
154
reorder(const sp<LayerBase> & layer,Vector<sp<LayerBase>>::compar_t cmp)155 ssize_t SurfaceFlinger::LayerVector::reorder(
156 const sp<LayerBase>& layer,
157 Vector< sp<LayerBase> >::compar_t cmp)
158 {
159 // XXX: it's a little lame. but oh well...
160 ssize_t err = remove(layer);
161 if (err >=0)
162 err = add(layer, cmp);
163 return err;
164 }
165
166 // ---------------------------------------------------------------------------
167 #if 0
168 #pragma mark -
169 #endif
170
SurfaceFlinger()171 SurfaceFlinger::SurfaceFlinger()
172 : BnSurfaceComposer(), Thread(false),
173 mTransactionFlags(0),
174 mTransactionCount(0),
175 mResizeTransationPending(false),
176 mLayersRemoved(false),
177 mBootTime(systemTime()),
178 mHardwareTest("android.permission.HARDWARE_TEST"),
179 mAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"),
180 mDump("android.permission.DUMP"),
181 mVisibleRegionsDirty(false),
182 mDeferReleaseConsole(false),
183 mFreezeDisplay(false),
184 mFreezeCount(0),
185 mFreezeDisplayTime(0),
186 mDebugRegion(0),
187 mDebugBackground(0),
188 mDebugInSwapBuffers(0),
189 mLastSwapBufferTime(0),
190 mDebugInTransaction(0),
191 mLastTransactionTime(0),
192 mBootFinished(false),
193 mConsoleSignals(0),
194 mSecureFrameBuffer(0)
195 {
196 init();
197 }
198
init()199 void SurfaceFlinger::init()
200 {
201 LOGI("SurfaceFlinger is starting");
202
203 // debugging stuff...
204 char value[PROPERTY_VALUE_MAX];
205 property_get("debug.sf.showupdates", value, "0");
206 mDebugRegion = atoi(value);
207 property_get("debug.sf.showbackground", value, "0");
208 mDebugBackground = atoi(value);
209
210 LOGI_IF(mDebugRegion, "showupdates enabled");
211 LOGI_IF(mDebugBackground, "showbackground enabled");
212 }
213
~SurfaceFlinger()214 SurfaceFlinger::~SurfaceFlinger()
215 {
216 glDeleteTextures(1, &mWormholeTexName);
217 }
218
getOverlayEngine() const219 overlay_control_device_t* SurfaceFlinger::getOverlayEngine() const
220 {
221 return graphicPlane(0).displayHardware().getOverlayEngine();
222 }
223
getCblk() const224 sp<IMemoryHeap> SurfaceFlinger::getCblk() const
225 {
226 return mServerHeap;
227 }
228
createConnection()229 sp<ISurfaceFlingerClient> SurfaceFlinger::createConnection()
230 {
231 Mutex::Autolock _l(mStateLock);
232 uint32_t token = mTokens.acquire();
233
234 sp<Client> client = new Client(token, this);
235 if (client->ctrlblk == 0) {
236 mTokens.release(token);
237 return 0;
238 }
239 status_t err = mClientsMap.add(token, client);
240 if (err < 0) {
241 mTokens.release(token);
242 return 0;
243 }
244 sp<BClient> bclient =
245 new BClient(this, token, client->getControlBlockMemory());
246 return bclient;
247 }
248
destroyConnection(ClientID cid)249 void SurfaceFlinger::destroyConnection(ClientID cid)
250 {
251 Mutex::Autolock _l(mStateLock);
252 sp<Client> client = mClientsMap.valueFor(cid);
253 if (client != 0) {
254 // free all the layers this client owns
255 Vector< wp<LayerBaseClient> > layers(client->getLayers());
256 const size_t count = layers.size();
257 for (size_t i=0 ; i<count ; i++) {
258 sp<LayerBaseClient> layer(layers[i].promote());
259 if (layer != 0) {
260 purgatorizeLayer_l(layer);
261 }
262 }
263
264 // the resources associated with this client will be freed
265 // during the next transaction, after these surfaces have been
266 // properly removed from the screen
267
268 // remove this client from our ClientID->Client mapping.
269 mClientsMap.removeItem(cid);
270
271 // and add it to the list of disconnected clients
272 mDisconnectedClients.add(client);
273
274 // request a transaction
275 setTransactionFlags(eTransactionNeeded);
276 }
277 }
278
graphicPlane(int dpy) const279 const GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const
280 {
281 LOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy);
282 const GraphicPlane& plane(mGraphicPlanes[dpy]);
283 return plane;
284 }
285
graphicPlane(int dpy)286 GraphicPlane& SurfaceFlinger::graphicPlane(int dpy)
287 {
288 return const_cast<GraphicPlane&>(
289 const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy));
290 }
291
bootFinished()292 void SurfaceFlinger::bootFinished()
293 {
294 const nsecs_t now = systemTime();
295 const nsecs_t duration = now - mBootTime;
296 LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
297 mBootFinished = true;
298 property_set("ctl.stop", "bootanim");
299 }
300
onFirstRef()301 void SurfaceFlinger::onFirstRef()
302 {
303 run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
304
305 // Wait for the main thread to be done with its initialization
306 mReadyToRunBarrier.wait();
307 }
308
pack565(int r,int g,int b)309 static inline uint16_t pack565(int r, int g, int b) {
310 return (r<<11)|(g<<5)|b;
311 }
312
readyToRun()313 status_t SurfaceFlinger::readyToRun()
314 {
315 LOGI( "SurfaceFlinger's main thread ready to run. "
316 "Initializing graphics H/W...");
317
318 // we only support one display currently
319 int dpy = 0;
320
321 {
322 // initialize the main display
323 GraphicPlane& plane(graphicPlane(dpy));
324 DisplayHardware* const hw = new DisplayHardware(this, dpy);
325 plane.setDisplayHardware(hw);
326 }
327
328 // create the shared control-block
329 mServerHeap = new MemoryHeapBase(4096,
330 MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");
331 LOGE_IF(mServerHeap==0, "can't create shared memory dealer");
332
333 mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase());
334 LOGE_IF(mServerCblk==0, "can't get to shared control block's address");
335
336 new(mServerCblk) surface_flinger_cblk_t;
337
338 // initialize primary screen
339 // (other display should be initialized in the same manner, but
340 // asynchronously, as they could come and go. None of this is supported
341 // yet).
342 const GraphicPlane& plane(graphicPlane(dpy));
343 const DisplayHardware& hw = plane.displayHardware();
344 const uint32_t w = hw.getWidth();
345 const uint32_t h = hw.getHeight();
346 const uint32_t f = hw.getFormat();
347 hw.makeCurrent();
348
349 // initialize the shared control block
350 mServerCblk->connected |= 1<<dpy;
351 display_cblk_t* dcblk = mServerCblk->displays + dpy;
352 memset(dcblk, 0, sizeof(display_cblk_t));
353 dcblk->w = w;
354 dcblk->h = h;
355 dcblk->format = f;
356 dcblk->orientation = ISurfaceComposer::eOrientationDefault;
357 dcblk->xdpi = hw.getDpiX();
358 dcblk->ydpi = hw.getDpiY();
359 dcblk->fps = hw.getRefreshRate();
360 dcblk->density = hw.getDensity();
361 asm volatile ("":::"memory");
362
363 // Initialize OpenGL|ES
364 glActiveTexture(GL_TEXTURE0);
365 glBindTexture(GL_TEXTURE_2D, 0);
366 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
367 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
368 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
369 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
370 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
371 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
372 glPixelStorei(GL_PACK_ALIGNMENT, 4);
373 glEnableClientState(GL_VERTEX_ARRAY);
374 glEnable(GL_SCISSOR_TEST);
375 glShadeModel(GL_FLAT);
376 glDisable(GL_DITHER);
377 glDisable(GL_CULL_FACE);
378
379 const uint16_t g0 = pack565(0x0F,0x1F,0x0F);
380 const uint16_t g1 = pack565(0x17,0x2f,0x17);
381 const uint16_t textureData[4] = { g0, g1, g1, g0 };
382 glGenTextures(1, &mWormholeTexName);
383 glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
384 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
385 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
386 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
387 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
388 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,
389 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, textureData);
390
391 glViewport(0, 0, w, h);
392 glMatrixMode(GL_PROJECTION);
393 glLoadIdentity();
394 glOrthof(0, w, h, 0, 0, 1);
395
396 LayerDim::initDimmer(this, w, h);
397
398 mReadyToRunBarrier.open();
399
400 /*
401 * We're now ready to accept clients...
402 */
403
404 // start boot animation
405 property_set("ctl.start", "bootanim");
406
407 return NO_ERROR;
408 }
409
410 // ----------------------------------------------------------------------------
411 #if 0
412 #pragma mark -
413 #pragma mark Events Handler
414 #endif
415
waitForEvent()416 void SurfaceFlinger::waitForEvent()
417 {
418 while (true) {
419 nsecs_t timeout = -1;
420 if (UNLIKELY(isFrozen())) {
421 // wait 5 seconds
422 const nsecs_t freezeDisplayTimeout = ms2ns(5000);
423 const nsecs_t now = systemTime();
424 if (mFreezeDisplayTime == 0) {
425 mFreezeDisplayTime = now;
426 }
427 nsecs_t waitTime = freezeDisplayTimeout - (now - mFreezeDisplayTime);
428 timeout = waitTime>0 ? waitTime : 0;
429 }
430
431 MessageList::value_type msg = mEventQueue.waitMessage(timeout);
432 if (msg != 0) {
433 mFreezeDisplayTime = 0;
434 switch (msg->what) {
435 case MessageQueue::INVALIDATE:
436 // invalidate message, just return to the main loop
437 return;
438 }
439 } else {
440 // we timed out
441 if (isFrozen()) {
442 // we timed out and are still frozen
443 LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d",
444 mFreezeDisplay, mFreezeCount);
445 mFreezeCount = 0;
446 mFreezeDisplay = false;
447 return;
448 }
449 }
450 }
451 }
452
signalEvent()453 void SurfaceFlinger::signalEvent() {
454 mEventQueue.invalidate();
455 }
456
signal() const457 void SurfaceFlinger::signal() const {
458 // this is the IPC call
459 const_cast<SurfaceFlinger*>(this)->signalEvent();
460 }
461
signalDelayedEvent(nsecs_t delay)462 void SurfaceFlinger::signalDelayedEvent(nsecs_t delay)
463 {
464 mEventQueue.postMessage( new MessageBase(MessageQueue::INVALIDATE), delay);
465 }
466
467 // ----------------------------------------------------------------------------
468 #if 0
469 #pragma mark -
470 #pragma mark Main loop
471 #endif
472
threadLoop()473 bool SurfaceFlinger::threadLoop()
474 {
475 waitForEvent();
476
477 // check for transactions
478 if (UNLIKELY(mConsoleSignals)) {
479 handleConsoleEvents();
480 }
481
482 if (LIKELY(mTransactionCount == 0)) {
483 // if we're in a global transaction, don't do anything.
484 const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
485 uint32_t transactionFlags = getTransactionFlags(mask);
486 if (LIKELY(transactionFlags)) {
487 handleTransaction(transactionFlags);
488 }
489 }
490
491 // post surfaces (if needed)
492 handlePageFlip();
493
494 const DisplayHardware& hw(graphicPlane(0).displayHardware());
495 if (LIKELY(hw.canDraw() && !isFrozen())) {
496 // repaint the framebuffer (if needed)
497 handleRepaint();
498
499 // inform the h/w that we're done compositing
500 hw.compositionComplete();
501
502 // release the clients before we flip ('cause flip might block)
503 unlockClients();
504
505 postFramebuffer();
506 } else {
507 // pretend we did the post
508 unlockClients();
509 usleep(16667); // 60 fps period
510 }
511 return true;
512 }
513
postFramebuffer()514 void SurfaceFlinger::postFramebuffer()
515 {
516 if (!mInvalidRegion.isEmpty()) {
517 const DisplayHardware& hw(graphicPlane(0).displayHardware());
518 const nsecs_t now = systemTime();
519 mDebugInSwapBuffers = now;
520 hw.flip(mInvalidRegion);
521 mLastSwapBufferTime = systemTime() - now;
522 mDebugInSwapBuffers = 0;
523 mInvalidRegion.clear();
524 }
525 }
526
handleConsoleEvents()527 void SurfaceFlinger::handleConsoleEvents()
528 {
529 // something to do with the console
530 const DisplayHardware& hw = graphicPlane(0).displayHardware();
531
532 int what = android_atomic_and(0, &mConsoleSignals);
533 if (what & eConsoleAcquired) {
534 hw.acquireScreen();
535 }
536
537 if (mDeferReleaseConsole && hw.canDraw()) {
538 // We got the release signal before the acquire signal
539 mDeferReleaseConsole = false;
540 hw.releaseScreen();
541 }
542
543 if (what & eConsoleReleased) {
544 if (hw.canDraw()) {
545 hw.releaseScreen();
546 } else {
547 mDeferReleaseConsole = true;
548 }
549 }
550
551 mDirtyRegion.set(hw.bounds());
552 }
553
handleTransaction(uint32_t transactionFlags)554 void SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
555 {
556 Vector< sp<LayerBase> > ditchedLayers;
557
558 { // scope for the lock
559 Mutex::Autolock _l(mStateLock);
560 const nsecs_t now = systemTime();
561 mDebugInTransaction = now;
562 handleTransactionLocked(transactionFlags, ditchedLayers);
563 mLastTransactionTime = systemTime() - now;
564 mDebugInTransaction = 0;
565 }
566
567 // do this without lock held
568 const size_t count = ditchedLayers.size();
569 for (size_t i=0 ; i<count ; i++) {
570 if (ditchedLayers[i] != 0) {
571 //LOGD("ditching layer %p", ditchedLayers[i].get());
572 ditchedLayers[i]->ditch();
573 }
574 }
575 }
576
handleTransactionLocked(uint32_t transactionFlags,Vector<sp<LayerBase>> & ditchedLayers)577 void SurfaceFlinger::handleTransactionLocked(
578 uint32_t transactionFlags, Vector< sp<LayerBase> >& ditchedLayers)
579 {
580 const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
581 const size_t count = currentLayers.size();
582
583 /*
584 * Traversal of the children
585 * (perform the transaction for each of them if needed)
586 */
587
588 const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
589 if (layersNeedTransaction) {
590 for (size_t i=0 ; i<count ; i++) {
591 const sp<LayerBase>& layer = currentLayers[i];
592 uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
593 if (!trFlags) continue;
594
595 const uint32_t flags = layer->doTransaction(0);
596 if (flags & Layer::eVisibleRegion)
597 mVisibleRegionsDirty = true;
598 }
599 }
600
601 /*
602 * Perform our own transaction if needed
603 */
604
605 if (transactionFlags & eTransactionNeeded) {
606 if (mCurrentState.orientation != mDrawingState.orientation) {
607 // the orientation has changed, recompute all visible regions
608 // and invalidate everything.
609
610 const int dpy = 0;
611 const int orientation = mCurrentState.orientation;
612 const uint32_t type = mCurrentState.orientationType;
613 GraphicPlane& plane(graphicPlane(dpy));
614 plane.setOrientation(orientation);
615
616 // update the shared control block
617 const DisplayHardware& hw(plane.displayHardware());
618 volatile display_cblk_t* dcblk = mServerCblk->displays + dpy;
619 dcblk->orientation = orientation;
620 if (orientation & eOrientationSwapMask) {
621 // 90 or 270 degrees orientation
622 dcblk->w = hw.getHeight();
623 dcblk->h = hw.getWidth();
624 } else {
625 dcblk->w = hw.getWidth();
626 dcblk->h = hw.getHeight();
627 }
628
629 mVisibleRegionsDirty = true;
630 mDirtyRegion.set(hw.bounds());
631 mFreezeDisplayTime = 0;
632 }
633
634 if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) {
635 // freezing or unfreezing the display -> trigger animation if needed
636 mFreezeDisplay = mCurrentState.freezeDisplay;
637 }
638
639 if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
640 // layers have been added
641 mVisibleRegionsDirty = true;
642 }
643
644 // some layers might have been removed, so
645 // we need to update the regions they're exposing.
646 if (mLayersRemoved) {
647 mLayersRemoved = false;
648 mVisibleRegionsDirty = true;
649 const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
650 const size_t count = previousLayers.size();
651 for (size_t i=0 ; i<count ; i++) {
652 const sp<LayerBase>& layer(previousLayers[i]);
653 if (currentLayers.indexOf( layer ) < 0) {
654 // this layer is not visible anymore
655 ditchedLayers.add(layer);
656 mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen);
657 }
658 }
659 }
660
661 // get rid of all resources we don't need anymore
662 // (layers and clients)
663 free_resources_l();
664 }
665
666 commitTransaction();
667 }
668
getFreezeLock() const669 sp<FreezeLock> SurfaceFlinger::getFreezeLock() const
670 {
671 return new FreezeLock(const_cast<SurfaceFlinger *>(this));
672 }
673
computeVisibleRegions(LayerVector & currentLayers,Region & dirtyRegion,Region & opaqueRegion)674 void SurfaceFlinger::computeVisibleRegions(
675 LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
676 {
677 const GraphicPlane& plane(graphicPlane(0));
678 const Transform& planeTransform(plane.transform());
679
680 Region aboveOpaqueLayers;
681 Region aboveCoveredLayers;
682 Region dirty;
683
684 bool secureFrameBuffer = false;
685
686 size_t i = currentLayers.size();
687 while (i--) {
688 const sp<LayerBase>& layer = currentLayers[i];
689 layer->validateVisibility(planeTransform);
690
691 // start with the whole surface at its current location
692 const Layer::State& s(layer->drawingState());
693
694 // handle hidden surfaces by setting the visible region to empty
695 Region opaqueRegion;
696 Region visibleRegion;
697 Region coveredRegion;
698 if (LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
699 const bool translucent = layer->needsBlending();
700 const Rect bounds(layer->visibleBounds());
701 visibleRegion.set(bounds);
702 coveredRegion = visibleRegion;
703
704 // Remove the transparent area from the visible region
705 if (translucent) {
706 visibleRegion.subtractSelf(layer->transparentRegionScreen);
707 }
708
709 // compute the opaque region
710 if (s.alpha==255 && !translucent && layer->getOrientation()>=0) {
711 // the opaque region is the visible region
712 opaqueRegion = visibleRegion;
713 }
714 }
715
716 // subtract the opaque region covered by the layers above us
717 visibleRegion.subtractSelf(aboveOpaqueLayers);
718 coveredRegion.andSelf(aboveCoveredLayers);
719
720 // compute this layer's dirty region
721 if (layer->contentDirty) {
722 // we need to invalidate the whole region
723 dirty = visibleRegion;
724 // as well, as the old visible region
725 dirty.orSelf(layer->visibleRegionScreen);
726 layer->contentDirty = false;
727 } else {
728 /* compute the exposed region:
729 * exposed = what's VISIBLE and NOT COVERED now
730 * but was COVERED before
731 */
732 dirty = (visibleRegion - coveredRegion) & layer->coveredRegionScreen;
733 }
734 dirty.subtractSelf(aboveOpaqueLayers);
735
736 // accumulate to the screen dirty region
737 dirtyRegion.orSelf(dirty);
738
739 // Update aboveOpaqueLayers/aboveCoveredLayers for next (lower) layer
740 aboveOpaqueLayers.orSelf(opaqueRegion);
741 aboveCoveredLayers.orSelf(visibleRegion);
742
743 // Store the visible region is screen space
744 layer->setVisibleRegion(visibleRegion);
745 layer->setCoveredRegion(coveredRegion);
746
747 // If a secure layer is partially visible, lock-down the screen!
748 if (layer->isSecure() && !visibleRegion.isEmpty()) {
749 secureFrameBuffer = true;
750 }
751 }
752
753 // invalidate the areas where a layer was removed
754 dirtyRegion.orSelf(mDirtyRegionRemovedLayer);
755 mDirtyRegionRemovedLayer.clear();
756
757 mSecureFrameBuffer = secureFrameBuffer;
758 opaqueRegion = aboveOpaqueLayers;
759 }
760
761
commitTransaction()762 void SurfaceFlinger::commitTransaction()
763 {
764 mDrawingState = mCurrentState;
765 mResizeTransationPending = false;
766 mTransactionCV.broadcast();
767 }
768
handlePageFlip()769 void SurfaceFlinger::handlePageFlip()
770 {
771 bool visibleRegions = mVisibleRegionsDirty;
772 LayerVector& currentLayers = const_cast<LayerVector&>(mDrawingState.layersSortedByZ);
773 visibleRegions |= lockPageFlip(currentLayers);
774
775 const DisplayHardware& hw = graphicPlane(0).displayHardware();
776 const Region screenRegion(hw.bounds());
777 if (visibleRegions) {
778 Region opaqueRegion;
779 computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion);
780 mWormholeRegion = screenRegion.subtract(opaqueRegion);
781 mVisibleRegionsDirty = false;
782 }
783
784 unlockPageFlip(currentLayers);
785 mDirtyRegion.andSelf(screenRegion);
786 }
787
lockPageFlip(const LayerVector & currentLayers)788 bool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers)
789 {
790 bool recomputeVisibleRegions = false;
791 size_t count = currentLayers.size();
792 sp<LayerBase> const* layers = currentLayers.array();
793 for (size_t i=0 ; i<count ; i++) {
794 const sp<LayerBase>& layer = layers[i];
795 layer->lockPageFlip(recomputeVisibleRegions);
796 }
797 return recomputeVisibleRegions;
798 }
799
unlockPageFlip(const LayerVector & currentLayers)800 void SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
801 {
802 const GraphicPlane& plane(graphicPlane(0));
803 const Transform& planeTransform(plane.transform());
804 size_t count = currentLayers.size();
805 sp<LayerBase> const* layers = currentLayers.array();
806 for (size_t i=0 ; i<count ; i++) {
807 const sp<LayerBase>& layer = layers[i];
808 layer->unlockPageFlip(planeTransform, mDirtyRegion);
809 }
810 }
811
812
handleRepaint()813 void SurfaceFlinger::handleRepaint()
814 {
815 // compute the invalid region
816 mInvalidRegion.orSelf(mDirtyRegion);
817 if (mInvalidRegion.isEmpty()) {
818 // nothing to do
819 return;
820 }
821
822 if (UNLIKELY(mDebugRegion)) {
823 debugFlashRegions();
824 }
825
826 // set the frame buffer
827 const DisplayHardware& hw(graphicPlane(0).displayHardware());
828 glMatrixMode(GL_MODELVIEW);
829 glLoadIdentity();
830
831 uint32_t flags = hw.getFlags();
832 if ((flags & DisplayHardware::SWAP_RECTANGLE) ||
833 (flags & DisplayHardware::BUFFER_PRESERVED))
834 {
835 // we can redraw only what's dirty, but since SWAP_RECTANGLE only
836 // takes a rectangle, we must make sure to update that whole
837 // rectangle in that case
838 if (flags & DisplayHardware::SWAP_RECTANGLE) {
839 // FIXME: we really should be able to pass a region to
840 // SWAP_RECTANGLE so that we don't have to redraw all this.
841 mDirtyRegion.set(mInvalidRegion.bounds());
842 } else {
843 // in the BUFFER_PRESERVED case, obviously, we can update only
844 // what's needed and nothing more.
845 // NOTE: this is NOT a common case, as preserving the backbuffer
846 // is costly and usually involves copying the whole update back.
847 }
848 } else {
849 if (flags & DisplayHardware::PARTIAL_UPDATES) {
850 // We need to redraw the rectangle that will be updated
851 // (pushed to the framebuffer).
852 // This is needed because PARTIAL_UPDATES only takes one
853 // rectangle instead of a region (see DisplayHardware::flip())
854 mDirtyRegion.set(mInvalidRegion.bounds());
855 } else {
856 // we need to redraw everything (the whole screen)
857 mDirtyRegion.set(hw.bounds());
858 mInvalidRegion = mDirtyRegion;
859 }
860 }
861
862 // compose all surfaces
863 composeSurfaces(mDirtyRegion);
864
865 // clear the dirty regions
866 mDirtyRegion.clear();
867 }
868
composeSurfaces(const Region & dirty)869 void SurfaceFlinger::composeSurfaces(const Region& dirty)
870 {
871 if (UNLIKELY(!mWormholeRegion.isEmpty())) {
872 // should never happen unless the window manager has a bug
873 // draw something...
874 drawWormhole();
875 }
876 const SurfaceFlinger& flinger(*this);
877 const LayerVector& drawingLayers(mDrawingState.layersSortedByZ);
878 const size_t count = drawingLayers.size();
879 sp<LayerBase> const* const layers = drawingLayers.array();
880 for (size_t i=0 ; i<count ; ++i) {
881 const sp<LayerBase>& layer = layers[i];
882 const Region& visibleRegion(layer->visibleRegionScreen);
883 if (!visibleRegion.isEmpty()) {
884 const Region clip(dirty.intersect(visibleRegion));
885 if (!clip.isEmpty()) {
886 layer->draw(clip);
887 }
888 }
889 }
890 }
891
unlockClients()892 void SurfaceFlinger::unlockClients()
893 {
894 const LayerVector& drawingLayers(mDrawingState.layersSortedByZ);
895 const size_t count = drawingLayers.size();
896 sp<LayerBase> const* const layers = drawingLayers.array();
897 for (size_t i=0 ; i<count ; ++i) {
898 const sp<LayerBase>& layer = layers[i];
899 layer->finishPageFlip();
900 }
901 }
902
debugFlashRegions()903 void SurfaceFlinger::debugFlashRegions()
904 {
905 const DisplayHardware& hw(graphicPlane(0).displayHardware());
906 const uint32_t flags = hw.getFlags();
907
908 if (!((flags & DisplayHardware::SWAP_RECTANGLE) ||
909 (flags & DisplayHardware::BUFFER_PRESERVED))) {
910 const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ?
911 mDirtyRegion.bounds() : hw.bounds());
912 composeSurfaces(repaint);
913 }
914
915 glDisable(GL_TEXTURE_2D);
916 glDisable(GL_BLEND);
917 glDisable(GL_DITHER);
918 glDisable(GL_SCISSOR_TEST);
919
920 static int toggle = 0;
921 toggle = 1 - toggle;
922 if (toggle) {
923 glColor4x(0x10000, 0, 0x10000, 0x10000);
924 } else {
925 glColor4x(0x10000, 0x10000, 0, 0x10000);
926 }
927
928 Region::const_iterator it = mDirtyRegion.begin();
929 Region::const_iterator const end = mDirtyRegion.end();
930 while (it != end) {
931 const Rect& r = *it++;
932 GLfloat vertices[][2] = {
933 { r.left, r.top },
934 { r.left, r.bottom },
935 { r.right, r.bottom },
936 { r.right, r.top }
937 };
938 glVertexPointer(2, GL_FLOAT, 0, vertices);
939 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
940 }
941
942 if (mInvalidRegion.isEmpty()) {
943 mDirtyRegion.dump("mDirtyRegion");
944 mInvalidRegion.dump("mInvalidRegion");
945 }
946 hw.flip(mInvalidRegion);
947
948 if (mDebugRegion > 1)
949 usleep(mDebugRegion * 1000);
950
951 glEnable(GL_SCISSOR_TEST);
952 //mDirtyRegion.dump("mDirtyRegion");
953 }
954
drawWormhole() const955 void SurfaceFlinger::drawWormhole() const
956 {
957 const Region region(mWormholeRegion.intersect(mDirtyRegion));
958 if (region.isEmpty())
959 return;
960
961 const DisplayHardware& hw(graphicPlane(0).displayHardware());
962 const int32_t width = hw.getWidth();
963 const int32_t height = hw.getHeight();
964
965 glDisable(GL_BLEND);
966 glDisable(GL_DITHER);
967
968 if (LIKELY(!mDebugBackground)) {
969 glClearColorx(0,0,0,0);
970 Region::const_iterator it = region.begin();
971 Region::const_iterator const end = region.end();
972 while (it != end) {
973 const Rect& r = *it++;
974 const GLint sy = height - (r.top + r.height());
975 glScissor(r.left, sy, r.width(), r.height());
976 glClear(GL_COLOR_BUFFER_BIT);
977 }
978 } else {
979 const GLshort vertices[][2] = { { 0, 0 }, { width, 0 },
980 { width, height }, { 0, height } };
981 const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 }, { 1, 1 }, { 0, 1 } };
982 glVertexPointer(2, GL_SHORT, 0, vertices);
983 glTexCoordPointer(2, GL_SHORT, 0, tcoords);
984 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
985 glEnable(GL_TEXTURE_2D);
986 glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
987 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
988 glMatrixMode(GL_TEXTURE);
989 glLoadIdentity();
990 glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1);
991 Region::const_iterator it = region.begin();
992 Region::const_iterator const end = region.end();
993 while (it != end) {
994 const Rect& r = *it++;
995 const GLint sy = height - (r.top + r.height());
996 glScissor(r.left, sy, r.width(), r.height());
997 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
998 }
999 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1000 }
1001 }
1002
debugShowFPS() const1003 void SurfaceFlinger::debugShowFPS() const
1004 {
1005 static int mFrameCount;
1006 static int mLastFrameCount = 0;
1007 static nsecs_t mLastFpsTime = 0;
1008 static float mFps = 0;
1009 mFrameCount++;
1010 nsecs_t now = systemTime();
1011 nsecs_t diff = now - mLastFpsTime;
1012 if (diff > ms2ns(250)) {
1013 mFps = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
1014 mLastFpsTime = now;
1015 mLastFrameCount = mFrameCount;
1016 }
1017 // XXX: mFPS has the value we want
1018 }
1019
addLayer(const sp<LayerBase> & layer)1020 status_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer)
1021 {
1022 Mutex::Autolock _l(mStateLock);
1023 addLayer_l(layer);
1024 setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1025 return NO_ERROR;
1026 }
1027
removeLayer(const sp<LayerBase> & layer)1028 status_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
1029 {
1030 Mutex::Autolock _l(mStateLock);
1031 status_t err = purgatorizeLayer_l(layer);
1032 if (err == NO_ERROR)
1033 setTransactionFlags(eTransactionNeeded);
1034 return err;
1035 }
1036
invalidateLayerVisibility(const sp<LayerBase> & layer)1037 status_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer)
1038 {
1039 layer->forceVisibilityTransaction();
1040 setTransactionFlags(eTraversalNeeded);
1041 return NO_ERROR;
1042 }
1043
addLayer_l(const sp<LayerBase> & layer)1044 status_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
1045 {
1046 if (layer == 0)
1047 return BAD_VALUE;
1048 ssize_t i = mCurrentState.layersSortedByZ.add(
1049 layer, &LayerBase::compareCurrentStateZ);
1050 sp<LayerBaseClient> lbc = LayerBase::dynamicCast< LayerBaseClient* >(layer.get());
1051 if (lbc != 0) {
1052 mLayerMap.add(lbc->serverIndex(), lbc);
1053 }
1054 return NO_ERROR;
1055 }
1056
removeLayer_l(const sp<LayerBase> & layerBase)1057 status_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
1058 {
1059 ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1060 if (index >= 0) {
1061 mLayersRemoved = true;
1062 sp<LayerBaseClient> layer =
1063 LayerBase::dynamicCast< LayerBaseClient* >(layerBase.get());
1064 if (layer != 0) {
1065 mLayerMap.removeItem(layer->serverIndex());
1066 }
1067 return NO_ERROR;
1068 }
1069 return status_t(index);
1070 }
1071
purgatorizeLayer_l(const sp<LayerBase> & layerBase)1072 status_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
1073 {
1074 // remove the layer from the main list (through a transaction).
1075 ssize_t err = removeLayer_l(layerBase);
1076
1077 layerBase->onRemoved();
1078
1079 // it's possible that we don't find a layer, because it might
1080 // have been destroyed already -- this is not technically an error
1081 // from the user because there is a race between BClient::destroySurface(),
1082 // ~BClient() and ~ISurface().
1083 return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
1084 }
1085
1086
free_resources_l()1087 void SurfaceFlinger::free_resources_l()
1088 {
1089 // free resources associated with disconnected clients
1090 Vector< sp<Client> >& disconnectedClients(mDisconnectedClients);
1091 const size_t count = disconnectedClients.size();
1092 for (size_t i=0 ; i<count ; i++) {
1093 sp<Client> client = disconnectedClients[i];
1094 mTokens.release(client->cid);
1095 }
1096 disconnectedClients.clear();
1097 }
1098
getTransactionFlags(uint32_t flags)1099 uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1100 {
1101 return android_atomic_and(~flags, &mTransactionFlags) & flags;
1102 }
1103
setTransactionFlags(uint32_t flags,nsecs_t delay)1104 uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags, nsecs_t delay)
1105 {
1106 uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1107 if ((old & flags)==0) { // wake the server up
1108 if (delay > 0) {
1109 signalDelayedEvent(delay);
1110 } else {
1111 signalEvent();
1112 }
1113 }
1114 return old;
1115 }
1116
openGlobalTransaction()1117 void SurfaceFlinger::openGlobalTransaction()
1118 {
1119 android_atomic_inc(&mTransactionCount);
1120 }
1121
closeGlobalTransaction()1122 void SurfaceFlinger::closeGlobalTransaction()
1123 {
1124 if (android_atomic_dec(&mTransactionCount) == 1) {
1125 signalEvent();
1126
1127 // if there is a transaction with a resize, wait for it to
1128 // take effect before returning.
1129 Mutex::Autolock _l(mStateLock);
1130 while (mResizeTransationPending) {
1131 status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
1132 if (CC_UNLIKELY(err != NO_ERROR)) {
1133 // just in case something goes wrong in SF, return to the
1134 // called after a few seconds.
1135 LOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
1136 mResizeTransationPending = false;
1137 break;
1138 }
1139 }
1140 }
1141 }
1142
freezeDisplay(DisplayID dpy,uint32_t flags)1143 status_t SurfaceFlinger::freezeDisplay(DisplayID dpy, uint32_t flags)
1144 {
1145 if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1146 return BAD_VALUE;
1147
1148 Mutex::Autolock _l(mStateLock);
1149 mCurrentState.freezeDisplay = 1;
1150 setTransactionFlags(eTransactionNeeded);
1151
1152 // flags is intended to communicate some sort of animation behavior
1153 // (for instance fading)
1154 return NO_ERROR;
1155 }
1156
unfreezeDisplay(DisplayID dpy,uint32_t flags)1157 status_t SurfaceFlinger::unfreezeDisplay(DisplayID dpy, uint32_t flags)
1158 {
1159 if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1160 return BAD_VALUE;
1161
1162 Mutex::Autolock _l(mStateLock);
1163 mCurrentState.freezeDisplay = 0;
1164 setTransactionFlags(eTransactionNeeded);
1165
1166 // flags is intended to communicate some sort of animation behavior
1167 // (for instance fading)
1168 return NO_ERROR;
1169 }
1170
setOrientation(DisplayID dpy,int orientation,uint32_t flags)1171 int SurfaceFlinger::setOrientation(DisplayID dpy,
1172 int orientation, uint32_t flags)
1173 {
1174 if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1175 return BAD_VALUE;
1176
1177 Mutex::Autolock _l(mStateLock);
1178 if (mCurrentState.orientation != orientation) {
1179 if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
1180 mCurrentState.orientationType = flags;
1181 mCurrentState.orientation = orientation;
1182 setTransactionFlags(eTransactionNeeded);
1183 mTransactionCV.wait(mStateLock);
1184 } else {
1185 orientation = BAD_VALUE;
1186 }
1187 }
1188 return orientation;
1189 }
1190
createSurface(ClientID clientId,int pid,ISurfaceFlingerClient::surface_data_t * params,DisplayID d,uint32_t w,uint32_t h,PixelFormat format,uint32_t flags)1191 sp<ISurface> SurfaceFlinger::createSurface(ClientID clientId, int pid,
1192 ISurfaceFlingerClient::surface_data_t* params,
1193 DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
1194 uint32_t flags)
1195 {
1196 sp<LayerBaseClient> layer;
1197 sp<LayerBaseClient::Surface> surfaceHandle;
1198
1199 if (int32_t(w|h) < 0) {
1200 LOGE("createSurface() failed, w or h is negative (w=%d, h=%d)",
1201 int(w), int(h));
1202 return surfaceHandle;
1203 }
1204
1205 Mutex::Autolock _l(mStateLock);
1206 sp<Client> client = mClientsMap.valueFor(clientId);
1207 if (UNLIKELY(client == 0)) {
1208 LOGE("createSurface() failed, client not found (id=%d)", clientId);
1209 return surfaceHandle;
1210 }
1211
1212 //LOGD("createSurface for pid %d (%d x %d)", pid, w, h);
1213 int32_t id = client->generateId(pid);
1214 if (uint32_t(id) >= NUM_LAYERS_MAX) {
1215 LOGE("createSurface() failed, generateId = %d", id);
1216 return surfaceHandle;
1217 }
1218
1219 switch (flags & eFXSurfaceMask) {
1220 case eFXSurfaceNormal:
1221 if (UNLIKELY(flags & ePushBuffers)) {
1222 layer = createPushBuffersSurfaceLocked(client, d, id,
1223 w, h, flags);
1224 } else {
1225 layer = createNormalSurfaceLocked(client, d, id,
1226 w, h, flags, format);
1227 }
1228 break;
1229 case eFXSurfaceBlur:
1230 layer = createBlurSurfaceLocked(client, d, id, w, h, flags);
1231 break;
1232 case eFXSurfaceDim:
1233 layer = createDimSurfaceLocked(client, d, id, w, h, flags);
1234 break;
1235 }
1236
1237 if (layer != 0) {
1238 setTransactionFlags(eTransactionNeeded);
1239 surfaceHandle = layer->getSurface();
1240 if (surfaceHandle != 0) {
1241 params->token = surfaceHandle->getToken();
1242 params->identity = surfaceHandle->getIdentity();
1243 params->width = w;
1244 params->height = h;
1245 params->format = format;
1246 }
1247 }
1248
1249 return surfaceHandle;
1250 }
1251
createNormalSurfaceLocked(const sp<Client> & client,DisplayID display,int32_t id,uint32_t w,uint32_t h,uint32_t flags,PixelFormat & format)1252 sp<LayerBaseClient> SurfaceFlinger::createNormalSurfaceLocked(
1253 const sp<Client>& client, DisplayID display,
1254 int32_t id, uint32_t w, uint32_t h, uint32_t flags,
1255 PixelFormat& format)
1256 {
1257 // initialize the surfaces
1258 switch (format) { // TODO: take h/w into account
1259 case PIXEL_FORMAT_TRANSPARENT:
1260 case PIXEL_FORMAT_TRANSLUCENT:
1261 format = PIXEL_FORMAT_RGBA_8888;
1262 break;
1263 case PIXEL_FORMAT_OPAQUE:
1264 format = PIXEL_FORMAT_RGB_565;
1265 break;
1266 }
1267
1268 sp<Layer> layer = new Layer(this, display, client, id);
1269 status_t err = layer->setBuffers(w, h, format, flags);
1270 if (LIKELY(err == NO_ERROR)) {
1271 layer->initStates(w, h, flags);
1272 addLayer_l(layer);
1273 } else {
1274 LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
1275 layer.clear();
1276 }
1277 return layer;
1278 }
1279
createBlurSurfaceLocked(const sp<Client> & client,DisplayID display,int32_t id,uint32_t w,uint32_t h,uint32_t flags)1280 sp<LayerBaseClient> SurfaceFlinger::createBlurSurfaceLocked(
1281 const sp<Client>& client, DisplayID display,
1282 int32_t id, uint32_t w, uint32_t h, uint32_t flags)
1283 {
1284 sp<LayerBlur> layer = new LayerBlur(this, display, client, id);
1285 layer->initStates(w, h, flags);
1286 addLayer_l(layer);
1287 return layer;
1288 }
1289
createDimSurfaceLocked(const sp<Client> & client,DisplayID display,int32_t id,uint32_t w,uint32_t h,uint32_t flags)1290 sp<LayerBaseClient> SurfaceFlinger::createDimSurfaceLocked(
1291 const sp<Client>& client, DisplayID display,
1292 int32_t id, uint32_t w, uint32_t h, uint32_t flags)
1293 {
1294 sp<LayerDim> layer = new LayerDim(this, display, client, id);
1295 layer->initStates(w, h, flags);
1296 addLayer_l(layer);
1297 return layer;
1298 }
1299
createPushBuffersSurfaceLocked(const sp<Client> & client,DisplayID display,int32_t id,uint32_t w,uint32_t h,uint32_t flags)1300 sp<LayerBaseClient> SurfaceFlinger::createPushBuffersSurfaceLocked(
1301 const sp<Client>& client, DisplayID display,
1302 int32_t id, uint32_t w, uint32_t h, uint32_t flags)
1303 {
1304 sp<LayerBuffer> layer = new LayerBuffer(this, display, client, id);
1305 layer->initStates(w, h, flags);
1306 addLayer_l(layer);
1307 return layer;
1308 }
1309
removeSurface(SurfaceID index)1310 status_t SurfaceFlinger::removeSurface(SurfaceID index)
1311 {
1312 /*
1313 * called by the window manager, when a surface should be marked for
1314 * destruction.
1315 *
1316 * The surface is removed from the current and drawing lists, but placed
1317 * in the purgatory queue, so it's not destroyed right-away (we need
1318 * to wait for all client's references to go away first).
1319 */
1320
1321 status_t err = NAME_NOT_FOUND;
1322 Mutex::Autolock _l(mStateLock);
1323 sp<LayerBaseClient> layer = getLayerUser_l(index);
1324 if (layer != 0) {
1325 err = purgatorizeLayer_l(layer);
1326 if (err == NO_ERROR) {
1327 setTransactionFlags(eTransactionNeeded);
1328 }
1329 }
1330 return err;
1331 }
1332
destroySurface(const sp<LayerBaseClient> & layer)1333 status_t SurfaceFlinger::destroySurface(const sp<LayerBaseClient>& layer)
1334 {
1335 // called by ~ISurface() when all references are gone
1336
1337 class MessageDestroySurface : public MessageBase {
1338 SurfaceFlinger* flinger;
1339 sp<LayerBaseClient> layer;
1340 public:
1341 MessageDestroySurface(
1342 SurfaceFlinger* flinger, const sp<LayerBaseClient>& layer)
1343 : flinger(flinger), layer(layer) { }
1344 virtual bool handler() {
1345 sp<LayerBaseClient> l(layer);
1346 layer.clear(); // clear it outside of the lock;
1347 Mutex::Autolock _l(flinger->mStateLock);
1348 /*
1349 * remove the layer from the current list -- chances are that it's
1350 * not in the list anyway, because it should have been removed
1351 * already upon request of the client (eg: window manager).
1352 * However, a buggy client could have not done that.
1353 * Since we know we don't have any more clients, we don't need
1354 * to use the purgatory.
1355 */
1356 status_t err = flinger->removeLayer_l(l);
1357 LOGE_IF(err<0 && err != NAME_NOT_FOUND,
1358 "error removing layer=%p (%s)", l.get(), strerror(-err));
1359 return true;
1360 }
1361 };
1362
1363 mEventQueue.postMessage( new MessageDestroySurface(this, layer) );
1364 return NO_ERROR;
1365 }
1366
setClientState(ClientID cid,int32_t count,const layer_state_t * states)1367 status_t SurfaceFlinger::setClientState(
1368 ClientID cid,
1369 int32_t count,
1370 const layer_state_t* states)
1371 {
1372 Mutex::Autolock _l(mStateLock);
1373 uint32_t flags = 0;
1374 cid <<= 16;
1375 for (int i=0 ; i<count ; i++) {
1376 const layer_state_t& s = states[i];
1377 sp<LayerBaseClient> layer(getLayerUser_l(s.surface | cid));
1378 if (layer != 0) {
1379 const uint32_t what = s.what;
1380 if (what & ePositionChanged) {
1381 if (layer->setPosition(s.x, s.y))
1382 flags |= eTraversalNeeded;
1383 }
1384 if (what & eLayerChanged) {
1385 if (layer->setLayer(s.z)) {
1386 mCurrentState.layersSortedByZ.reorder(
1387 layer, &Layer::compareCurrentStateZ);
1388 // we need traversal (state changed)
1389 // AND transaction (list changed)
1390 flags |= eTransactionNeeded|eTraversalNeeded;
1391 }
1392 }
1393 if (what & eSizeChanged) {
1394 if (layer->setSize(s.w, s.h)) {
1395 flags |= eTraversalNeeded;
1396 mResizeTransationPending = true;
1397 }
1398 }
1399 if (what & eAlphaChanged) {
1400 if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1401 flags |= eTraversalNeeded;
1402 }
1403 if (what & eMatrixChanged) {
1404 if (layer->setMatrix(s.matrix))
1405 flags |= eTraversalNeeded;
1406 }
1407 if (what & eTransparentRegionChanged) {
1408 if (layer->setTransparentRegionHint(s.transparentRegion))
1409 flags |= eTraversalNeeded;
1410 }
1411 if (what & eVisibilityChanged) {
1412 if (layer->setFlags(s.flags, s.mask))
1413 flags |= eTraversalNeeded;
1414 }
1415 }
1416 }
1417 if (flags) {
1418 setTransactionFlags(flags);
1419 }
1420 return NO_ERROR;
1421 }
1422
getLayerUser_l(SurfaceID s) const1423 sp<LayerBaseClient> SurfaceFlinger::getLayerUser_l(SurfaceID s) const
1424 {
1425 sp<LayerBaseClient> layer = mLayerMap.valueFor(s);
1426 return layer;
1427 }
1428
screenReleased(int dpy)1429 void SurfaceFlinger::screenReleased(int dpy)
1430 {
1431 // this may be called by a signal handler, we can't do too much in here
1432 android_atomic_or(eConsoleReleased, &mConsoleSignals);
1433 signalEvent();
1434 }
1435
screenAcquired(int dpy)1436 void SurfaceFlinger::screenAcquired(int dpy)
1437 {
1438 // this may be called by a signal handler, we can't do too much in here
1439 android_atomic_or(eConsoleAcquired, &mConsoleSignals);
1440 signalEvent();
1441 }
1442
dump(int fd,const Vector<String16> & args)1443 status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
1444 {
1445 const size_t SIZE = 1024;
1446 char buffer[SIZE];
1447 String8 result;
1448 if (!mDump.checkCalling()) {
1449 snprintf(buffer, SIZE, "Permission Denial: "
1450 "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
1451 IPCThreadState::self()->getCallingPid(),
1452 IPCThreadState::self()->getCallingUid());
1453 result.append(buffer);
1454 } else {
1455
1456 // figure out if we're stuck somewhere
1457 const nsecs_t now = systemTime();
1458 const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
1459 const nsecs_t inTransaction(mDebugInTransaction);
1460 nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
1461 nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
1462
1463 // Try to get the main lock, but don't insist if we can't
1464 // (this would indicate SF is stuck, but we want to be able to
1465 // print something in dumpsys).
1466 int retry = 3;
1467 while (mStateLock.tryLock()<0 && --retry>=0) {
1468 usleep(1000000);
1469 }
1470 const bool locked(retry >= 0);
1471 if (!locked) {
1472 snprintf(buffer, SIZE,
1473 "SurfaceFlinger appears to be unresponsive, "
1474 "dumping anyways (no locks held)\n");
1475 result.append(buffer);
1476 }
1477
1478 size_t s = mClientsMap.size();
1479 char name[64];
1480 for (size_t i=0 ; i<s ; i++) {
1481 sp<Client> client = mClientsMap.valueAt(i);
1482 sprintf(name, " Client (id=0x%08x)", client->cid);
1483 client->dump(name);
1484 }
1485 const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
1486 const size_t count = currentLayers.size();
1487 for (size_t i=0 ; i<count ; i++) {
1488 /*** LayerBase ***/
1489 const sp<LayerBase>& layer = currentLayers[i];
1490 const Layer::State& s = layer->drawingState();
1491 snprintf(buffer, SIZE,
1492 "+ %s %p\n"
1493 " "
1494 "z=%9d, pos=(%4d,%4d), size=(%4d,%4d), "
1495 "needsBlending=%1d, needsDithering=%1d, invalidate=%1d, "
1496 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n",
1497 layer->getTypeID(), layer.get(),
1498 s.z, layer->tx(), layer->ty(), s.w, s.h,
1499 layer->needsBlending(), layer->needsDithering(),
1500 layer->contentDirty,
1501 s.alpha, s.flags,
1502 s.transform[0], s.transform[1],
1503 s.transform[2], s.transform[3]);
1504 result.append(buffer);
1505 buffer[0] = 0;
1506 /*** LayerBaseClient ***/
1507 sp<LayerBaseClient> lbc =
1508 LayerBase::dynamicCast< LayerBaseClient* >(layer.get());
1509 if (lbc != 0) {
1510 sp<Client> client(lbc->client.promote());
1511 snprintf(buffer, SIZE,
1512 " "
1513 "id=0x%08x, client=0x%08x, identity=%u\n",
1514 lbc->clientIndex(), client.get() ? client->cid : 0,
1515 lbc->getIdentity());
1516
1517 result.append(buffer);
1518 buffer[0] = 0;
1519 }
1520 /*** Layer ***/
1521 sp<Layer> l = LayerBase::dynamicCast< Layer* >(layer.get());
1522 if (l != 0) {
1523 SharedBufferStack::Statistics stats = l->lcblk->getStats();
1524 result.append( l->lcblk->dump(" ") );
1525 sp<const GraphicBuffer> buf0(l->getBuffer(0));
1526 sp<const GraphicBuffer> buf1(l->getBuffer(1));
1527 uint32_t w0=0, h0=0, s0=0;
1528 uint32_t w1=0, h1=0, s1=0;
1529 if (buf0 != 0) {
1530 w0 = buf0->getWidth();
1531 h0 = buf0->getHeight();
1532 s0 = buf0->getStride();
1533 }
1534 if (buf1 != 0) {
1535 w1 = buf1->getWidth();
1536 h1 = buf1->getHeight();
1537 s1 = buf1->getStride();
1538 }
1539 snprintf(buffer, SIZE,
1540 " "
1541 "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u],"
1542 " freezeLock=%p, dq-q-time=%u us\n",
1543 l->pixelFormat(),
1544 w0, h0, s0, w1, h1, s1,
1545 l->getFreezeLock().get(), stats.totalTime);
1546 result.append(buffer);
1547 buffer[0] = 0;
1548 }
1549 s.transparentRegion.dump(result, "transparentRegion");
1550 layer->transparentRegionScreen.dump(result, "transparentRegionScreen");
1551 layer->visibleRegionScreen.dump(result, "visibleRegionScreen");
1552 }
1553 mWormholeRegion.dump(result, "WormholeRegion");
1554 const DisplayHardware& hw(graphicPlane(0).displayHardware());
1555 snprintf(buffer, SIZE,
1556 " display frozen: %s, freezeCount=%d, orientation=%d, canDraw=%d\n",
1557 mFreezeDisplay?"yes":"no", mFreezeCount,
1558 mCurrentState.orientation, hw.canDraw());
1559 result.append(buffer);
1560 snprintf(buffer, SIZE,
1561 " last eglSwapBuffers() time: %f us\n"
1562 " last transaction time : %f us\n",
1563 mLastSwapBufferTime/1000.0, mLastTransactionTime/1000.0);
1564 result.append(buffer);
1565 if (inSwapBuffersDuration || !locked) {
1566 snprintf(buffer, SIZE, " eglSwapBuffers time: %f us\n",
1567 inSwapBuffersDuration/1000.0);
1568 result.append(buffer);
1569 }
1570 if (inTransactionDuration || !locked) {
1571 snprintf(buffer, SIZE, " transaction time: %f us\n",
1572 inTransactionDuration/1000.0);
1573 result.append(buffer);
1574 }
1575 snprintf(buffer, SIZE, " client count: %d\n", mClientsMap.size());
1576 result.append(buffer);
1577 const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
1578 alloc.dump(result);
1579
1580 if (locked) {
1581 mStateLock.unlock();
1582 }
1583 }
1584 write(fd, result.string(), result.size());
1585 return NO_ERROR;
1586 }
1587
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)1588 status_t SurfaceFlinger::onTransact(
1589 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1590 {
1591 switch (code) {
1592 case CREATE_CONNECTION:
1593 case OPEN_GLOBAL_TRANSACTION:
1594 case CLOSE_GLOBAL_TRANSACTION:
1595 case SET_ORIENTATION:
1596 case FREEZE_DISPLAY:
1597 case UNFREEZE_DISPLAY:
1598 case BOOT_FINISHED:
1599 {
1600 // codes that require permission check
1601 IPCThreadState* ipc = IPCThreadState::self();
1602 const int pid = ipc->getCallingPid();
1603 const int uid = ipc->getCallingUid();
1604 if ((uid != AID_GRAPHICS) && !mAccessSurfaceFlinger.check(pid, uid)) {
1605 LOGE("Permission Denial: "
1606 "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1607 return PERMISSION_DENIED;
1608 }
1609 }
1610 }
1611 status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
1612 if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
1613 CHECK_INTERFACE(ISurfaceComposer, data, reply);
1614 if (UNLIKELY(!mHardwareTest.checkCalling())) {
1615 IPCThreadState* ipc = IPCThreadState::self();
1616 const int pid = ipc->getCallingPid();
1617 const int uid = ipc->getCallingUid();
1618 LOGE("Permission Denial: "
1619 "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1620 return PERMISSION_DENIED;
1621 }
1622 int n;
1623 switch (code) {
1624 case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
1625 return NO_ERROR;
1626 case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
1627 return NO_ERROR;
1628 case 1002: // SHOW_UPDATES
1629 n = data.readInt32();
1630 mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
1631 return NO_ERROR;
1632 case 1003: // SHOW_BACKGROUND
1633 n = data.readInt32();
1634 mDebugBackground = n ? 1 : 0;
1635 return NO_ERROR;
1636 case 1004:{ // repaint everything
1637 Mutex::Autolock _l(mStateLock);
1638 const DisplayHardware& hw(graphicPlane(0).displayHardware());
1639 mDirtyRegion.set(hw.bounds()); // careful that's not thread-safe
1640 signalEvent();
1641 return NO_ERROR;
1642 }
1643 case 1005:{ // force transaction
1644 setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1645 return NO_ERROR;
1646 }
1647 case 1007: // set mFreezeCount
1648 mFreezeCount = data.readInt32();
1649 return NO_ERROR;
1650 case 1010: // interrogate.
1651 reply->writeInt32(0);
1652 reply->writeInt32(0);
1653 reply->writeInt32(mDebugRegion);
1654 reply->writeInt32(mDebugBackground);
1655 return NO_ERROR;
1656 case 1013: {
1657 Mutex::Autolock _l(mStateLock);
1658 const DisplayHardware& hw(graphicPlane(0).displayHardware());
1659 reply->writeInt32(hw.getPageFlipCount());
1660 }
1661 return NO_ERROR;
1662 }
1663 }
1664 return err;
1665 }
1666
1667 // ---------------------------------------------------------------------------
1668 #if 0
1669 #pragma mark -
1670 #endif
1671
Client(ClientID clientID,const sp<SurfaceFlinger> & flinger)1672 Client::Client(ClientID clientID, const sp<SurfaceFlinger>& flinger)
1673 : ctrlblk(0), cid(clientID), mPid(0), mBitmap(0), mFlinger(flinger)
1674 {
1675 const int pgsize = getpagesize();
1676 const int cblksize = ((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1));
1677
1678 mCblkHeap = new MemoryHeapBase(cblksize, 0,
1679 "SurfaceFlinger Client control-block");
1680
1681 ctrlblk = static_cast<SharedClient *>(mCblkHeap->getBase());
1682 if (ctrlblk) { // construct the shared structure in-place.
1683 new(ctrlblk) SharedClient;
1684 }
1685 }
1686
~Client()1687 Client::~Client() {
1688 if (ctrlblk) {
1689 ctrlblk->~SharedClient(); // destroy our shared-structure.
1690 }
1691 }
1692
generateId(int pid)1693 int32_t Client::generateId(int pid)
1694 {
1695 const uint32_t i = clz( ~mBitmap );
1696 if (i >= NUM_LAYERS_MAX) {
1697 return NO_MEMORY;
1698 }
1699 mPid = pid;
1700 mInUse.add(uint8_t(i));
1701 mBitmap |= 1<<(31-i);
1702 return i;
1703 }
1704
bindLayer(const sp<LayerBaseClient> & layer,int32_t id)1705 status_t Client::bindLayer(const sp<LayerBaseClient>& layer, int32_t id)
1706 {
1707 ssize_t idx = mInUse.indexOf(id);
1708 if (idx < 0)
1709 return NAME_NOT_FOUND;
1710 return mLayers.insertAt(layer, idx);
1711 }
1712
free(int32_t id)1713 void Client::free(int32_t id)
1714 {
1715 ssize_t idx = mInUse.remove(uint8_t(id));
1716 if (idx >= 0) {
1717 mBitmap &= ~(1<<(31-id));
1718 mLayers.removeItemsAt(idx);
1719 }
1720 }
1721
isValid(int32_t i) const1722 bool Client::isValid(int32_t i) const {
1723 return (uint32_t(i)<NUM_LAYERS_MAX) && (mBitmap & (1<<(31-i)));
1724 }
1725
getLayerUser(int32_t i) const1726 sp<LayerBaseClient> Client::getLayerUser(int32_t i) const {
1727 sp<LayerBaseClient> lbc;
1728 ssize_t idx = mInUse.indexOf(uint8_t(i));
1729 if (idx >= 0) {
1730 lbc = mLayers[idx].promote();
1731 LOGE_IF(lbc==0, "getLayerUser(i=%d), idx=%d is dead", int(i), int(idx));
1732 }
1733 return lbc;
1734 }
1735
dump(const char * what)1736 void Client::dump(const char* what)
1737 {
1738 }
1739
1740 // ---------------------------------------------------------------------------
1741 #if 0
1742 #pragma mark -
1743 #endif
1744
BClient(SurfaceFlinger * flinger,ClientID cid,const sp<IMemoryHeap> & cblk)1745 BClient::BClient(SurfaceFlinger *flinger, ClientID cid, const sp<IMemoryHeap>& cblk)
1746 : mId(cid), mFlinger(flinger), mCblk(cblk)
1747 {
1748 }
1749
~BClient()1750 BClient::~BClient() {
1751 // destroy all resources attached to this client
1752 mFlinger->destroyConnection(mId);
1753 }
1754
getControlBlock() const1755 sp<IMemoryHeap> BClient::getControlBlock() const {
1756 return mCblk;
1757 }
1758
createSurface(ISurfaceFlingerClient::surface_data_t * params,int pid,DisplayID display,uint32_t w,uint32_t h,PixelFormat format,uint32_t flags)1759 sp<ISurface> BClient::createSurface(
1760 ISurfaceFlingerClient::surface_data_t* params, int pid,
1761 DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
1762 uint32_t flags)
1763 {
1764 return mFlinger->createSurface(mId, pid, params, display, w, h, format, flags);
1765 }
1766
destroySurface(SurfaceID sid)1767 status_t BClient::destroySurface(SurfaceID sid)
1768 {
1769 sid |= (mId << 16); // add the client-part to id
1770 return mFlinger->removeSurface(sid);
1771 }
1772
setState(int32_t count,const layer_state_t * states)1773 status_t BClient::setState(int32_t count, const layer_state_t* states)
1774 {
1775 return mFlinger->setClientState(mId, count, states);
1776 }
1777
1778 // ---------------------------------------------------------------------------
1779
GraphicPlane()1780 GraphicPlane::GraphicPlane()
1781 : mHw(0)
1782 {
1783 }
1784
~GraphicPlane()1785 GraphicPlane::~GraphicPlane() {
1786 delete mHw;
1787 }
1788
initialized() const1789 bool GraphicPlane::initialized() const {
1790 return mHw ? true : false;
1791 }
1792
setDisplayHardware(DisplayHardware * hw)1793 void GraphicPlane::setDisplayHardware(DisplayHardware *hw) {
1794 mHw = hw;
1795 }
1796
setTransform(const Transform & tr)1797 void GraphicPlane::setTransform(const Transform& tr) {
1798 mTransform = tr;
1799 mGlobalTransform = mOrientationTransform * mTransform;
1800 }
1801
orientationToTransfrom(int orientation,int w,int h,Transform * tr)1802 status_t GraphicPlane::orientationToTransfrom(
1803 int orientation, int w, int h, Transform* tr)
1804 {
1805 float a, b, c, d, x, y;
1806 switch (orientation) {
1807 case ISurfaceComposer::eOrientationDefault:
1808 a=1; b=0; c=0; d=1; x=0; y=0;
1809 break;
1810 case ISurfaceComposer::eOrientation90:
1811 a=0; b=-1; c=1; d=0; x=w; y=0;
1812 break;
1813 case ISurfaceComposer::eOrientation180:
1814 a=-1; b=0; c=0; d=-1; x=w; y=h;
1815 break;
1816 case ISurfaceComposer::eOrientation270:
1817 a=0; b=1; c=-1; d=0; x=0; y=h;
1818 break;
1819 default:
1820 return BAD_VALUE;
1821 }
1822 tr->set(a, b, c, d);
1823 tr->set(x, y);
1824 return NO_ERROR;
1825 }
1826
setOrientation(int orientation)1827 status_t GraphicPlane::setOrientation(int orientation)
1828 {
1829 const DisplayHardware& hw(displayHardware());
1830 const float w = hw.getWidth();
1831 const float h = hw.getHeight();
1832
1833 if (orientation == ISurfaceComposer::eOrientationDefault) {
1834 // make sure the default orientation is optimal
1835 mOrientationTransform.reset();
1836 mOrientation = orientation;
1837 mGlobalTransform = mTransform;
1838 return NO_ERROR;
1839 }
1840
1841 // If the rotation can be handled in hardware, this is where
1842 // the magic should happen.
1843 if (UNLIKELY(orientation == 42)) {
1844 float a, b, c, d, x, y;
1845 const float r = (3.14159265f / 180.0f) * 42.0f;
1846 const float si = sinf(r);
1847 const float co = cosf(r);
1848 a=co; b=-si; c=si; d=co;
1849 x = si*(h*0.5f) + (1-co)*(w*0.5f);
1850 y =-si*(w*0.5f) + (1-co)*(h*0.5f);
1851 mOrientationTransform.set(a, b, c, d);
1852 mOrientationTransform.set(x, y);
1853 } else {
1854 GraphicPlane::orientationToTransfrom(orientation, w, h,
1855 &mOrientationTransform);
1856 }
1857 mOrientation = orientation;
1858 mGlobalTransform = mOrientationTransform * mTransform;
1859 return NO_ERROR;
1860 }
1861
displayHardware() const1862 const DisplayHardware& GraphicPlane::displayHardware() const {
1863 return *mHw;
1864 }
1865
transform() const1866 const Transform& GraphicPlane::transform() const {
1867 return mGlobalTransform;
1868 }
1869
getEGLDisplay() const1870 EGLDisplay GraphicPlane::getEGLDisplay() const {
1871 return mHw->getEGLDisplay();
1872 }
1873
1874 // ---------------------------------------------------------------------------
1875
1876 }; // namespace android
1877