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