• 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 #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