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