blob: 4c719e8d9b9a10c5ca83156796696179d8653200 [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 Project27629322009-01-09 17:51:23 -0800234overlay_control_device_t* SurfaceFlinger::getOverlayEngine() const
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -0800235{
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
The Android Open Source Project27629322009-01-09 17:51:23 -0800776 if (layer->contentDirty) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700777 // we need to invalidate the whole region
778 dirty = visibleRegion;
779 // as well, as the old visible region
780 dirty.orSelf(layer->visibleRegionScreen);
The Android Open Source Project27629322009-01-09 17:51:23 -0800781 layer->contentDirty = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700782 } 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,
The Android Open Source Project27629322009-01-09 17:51:23 -08001459 layer->needsBlending(), layer->contentDirty,
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001460 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;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001477 /*** Layer ***/
1478 Layer* const l = LayerBase::dynamicCast<Layer*>((LayerBase*)layer);
1479 if (l) {
1480 const LayerBitmap& buf0(l->getBuffer(0));
1481 const LayerBitmap& buf1(l->getBuffer(1));
1482 snprintf(buffer, SIZE,
1483 " "
1484 "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u], mTextureName=%d,"
1485 " freezeLock=%p, swapState=0x%08x\n",
1486 l->pixelFormat(),
1487 buf0.width(), buf0.height(), buf0.stride(),
1488 buf1.width(), buf1.height(), buf1.stride(),
1489 l->getTextureName(), l->getFreezeLock().get(),
1490 l->lcblk->swapState);
1491 }
1492 result.append(buffer);
1493 buffer[0] = 0;
1494 s.transparentRegion.dump(result, "transparentRegion");
1495 layer->transparentRegionScreen.dump(result, "transparentRegionScreen");
1496 layer->visibleRegionScreen.dump(result, "visibleRegionScreen");
1497 }
1498 mWormholeRegion.dump(result, "WormholeRegion");
1499 const DisplayHardware& hw(graphicPlane(0).displayHardware());
1500 snprintf(buffer, SIZE,
1501 " display frozen: %s, freezeCount=%d, orientation=%d, canDraw=%d\n",
1502 mFreezeDisplay?"yes":"no", mFreezeCount,
1503 mCurrentState.orientation, hw.canDraw());
1504 result.append(buffer);
1505
1506 sp<AllocatorInterface> allocator;
1507 if (mGPU != 0) {
1508 snprintf(buffer, SIZE, " GPU owner: %d\n", mGPU->getOwner());
1509 result.append(buffer);
1510 allocator = mGPU->getAllocator();
1511 if (allocator != 0) {
1512 allocator->dump(result, "GPU Allocator");
1513 }
1514 }
1515 allocator = mSurfaceHeapManager->getAllocator(NATIVE_MEMORY_TYPE_PMEM);
1516 if (allocator != 0) {
1517 allocator->dump(result, "PMEM Allocator");
1518 }
1519 }
1520 write(fd, result.string(), result.size());
1521 return NO_ERROR;
1522}
1523
1524status_t SurfaceFlinger::onTransact(
1525 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1526{
1527 switch (code) {
1528 case CREATE_CONNECTION:
1529 case OPEN_GLOBAL_TRANSACTION:
1530 case CLOSE_GLOBAL_TRANSACTION:
1531 case SET_ORIENTATION:
1532 case FREEZE_DISPLAY:
1533 case UNFREEZE_DISPLAY:
1534 case BOOT_FINISHED:
1535 case REVOKE_GPU:
1536 {
1537 // codes that require permission check
1538 IPCThreadState* ipc = IPCThreadState::self();
1539 const int pid = ipc->getCallingPid();
1540 const int self_pid = getpid();
1541 if (UNLIKELY(pid != self_pid)) {
1542 // we're called from a different process, do the real check
1543 if (!checkCallingPermission(
1544 String16("android.permission.ACCESS_SURFACE_FLINGER")))
1545 {
1546 const int uid = ipc->getCallingUid();
1547 LOGE("Permission Denial: "
1548 "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1549 return PERMISSION_DENIED;
1550 }
1551 }
1552 }
1553 }
1554
1555 status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
1556 if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
1557 if (code == 1012) {
1558 // take screen-shot of the front buffer
1559 if (UNLIKELY(checkCallingPermission(
1560 String16("android.permission.READ_FRAME_BUFFER")) == false))
1561 { // not allowed
1562 LOGE("Permission Denial: "
1563 "can't take screenshots from pid=%d, uid=%d\n",
1564 IPCThreadState::self()->getCallingPid(),
1565 IPCThreadState::self()->getCallingUid());
1566 return PERMISSION_DENIED;
1567 }
1568
1569 if (UNLIKELY(mSecureFrameBuffer)) {
1570 LOGE("A secure window is on screen: "
1571 "can't take screenshots from pid=%d, uid=%d\n",
1572 IPCThreadState::self()->getCallingPid(),
1573 IPCThreadState::self()->getCallingUid());
1574 return PERMISSION_DENIED;
1575 }
1576
1577 LOGI("Taking a screenshot...");
1578
1579 LayerScreenshot* l = new LayerScreenshot(this, 0);
1580
1581 Mutex::Autolock _l(mStateLock);
1582 const DisplayHardware& hw(graphicPlane(0).displayHardware());
1583 l->initStates(hw.getWidth(), hw.getHeight(), 0);
1584 l->setLayer(INT_MAX);
1585
1586 addLayer_l(l);
1587 setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1588
1589 l->takeScreenshot(mStateLock, reply);
1590
1591 removeLayer_l(l);
1592 setTransactionFlags(eTransactionNeeded);
1593 return NO_ERROR;
1594 } else {
1595 // HARDWARE_TEST stuff...
1596 if (UNLIKELY(checkCallingPermission(
1597 String16("android.permission.HARDWARE_TEST")) == false))
1598 { // not allowed
1599 LOGE("Permission Denial: pid=%d, uid=%d\n",
1600 IPCThreadState::self()->getCallingPid(),
1601 IPCThreadState::self()->getCallingUid());
1602 return PERMISSION_DENIED;
1603 }
1604 int n;
1605 switch (code) {
1606 case 1000: // SHOW_CPU
1607 n = data.readInt32();
1608 mDebugCpu = n ? 1 : 0;
1609 if (mDebugCpu) {
1610 if (mCpuGauge == 0) {
1611 mCpuGauge = new CPUGauge(this, ms2ns(500));
1612 }
1613 } else {
1614 if (mCpuGauge != 0) {
1615 mCpuGauge->requestExitAndWait();
1616 Mutex::Autolock _l(mDebugLock);
1617 mCpuGauge.clear();
1618 }
1619 }
1620 return NO_ERROR;
1621 case 1001: // SHOW_FPS
1622 n = data.readInt32();
1623 mDebugFps = n ? 1 : 0;
1624 return NO_ERROR;
1625 case 1002: // SHOW_UPDATES
1626 n = data.readInt32();
1627 mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
1628 return NO_ERROR;
1629 case 1003: // SHOW_BACKGROUND
1630 n = data.readInt32();
1631 mDebugBackground = n ? 1 : 0;
1632 return NO_ERROR;
1633 case 1004:{ // repaint everything
1634 Mutex::Autolock _l(mStateLock);
1635 const DisplayHardware& hw(graphicPlane(0).displayHardware());
1636 mDirtyRegion.set(hw.bounds()); // careful that's not thread-safe
1637 signalEvent();
1638 }
1639 return NO_ERROR;
1640 case 1005: // ask GPU revoke
1641 mGPU->friendlyRevoke();
1642 return NO_ERROR;
1643 case 1006: // revoke GPU
1644 mGPU->unconditionalRevoke();
1645 return NO_ERROR;
1646 case 1007: // set mFreezeCount
1647 mFreezeCount = data.readInt32();
1648 return NO_ERROR;
1649 case 1010: // interrogate.
1650 reply->writeInt32(mDebugCpu);
1651 reply->writeInt32(0);
1652 reply->writeInt32(mDebugRegion);
1653 reply->writeInt32(mDebugBackground);
1654 return NO_ERROR;
1655 case 1013: { // screenshot
1656 Mutex::Autolock _l(mStateLock);
1657 const DisplayHardware& hw(graphicPlane(0).displayHardware());
1658 reply->writeInt32(hw.getPageFlipCount());
1659 }
1660 return NO_ERROR;
1661 }
1662 }
1663 }
1664 return err;
1665}
1666
1667// ---------------------------------------------------------------------------
1668#if 0
1669#pragma mark -
1670#endif
1671
1672Client::Client(ClientID clientID, const sp<SurfaceFlinger>& flinger)
1673 : ctrlblk(0), cid(clientID), mPid(0), mBitmap(0), mFlinger(flinger)
1674{
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -08001675 mSharedHeapAllocator = getSurfaceHeapManager()->createHeap();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001676 const int pgsize = getpagesize();
1677 const int cblksize=((sizeof(per_client_cblk_t)+(pgsize-1))&~(pgsize-1));
1678 mCblkHeap = new MemoryDealer(cblksize);
1679 mCblkMemory = mCblkHeap->allocate(cblksize);
1680 if (mCblkMemory != 0) {
1681 ctrlblk = static_cast<per_client_cblk_t *>(mCblkMemory->pointer());
1682 if (ctrlblk) { // construct the shared structure in-place.
1683 new(ctrlblk) per_client_cblk_t;
1684 }
1685 }
1686}
1687
1688Client::~Client() {
1689 if (ctrlblk) {
1690 const int pgsize = getpagesize();
1691 ctrlblk->~per_client_cblk_t(); // destroy our shared-structure.
1692 }
1693}
1694
1695const sp<SurfaceHeapManager>& Client::getSurfaceHeapManager() const {
1696 return mFlinger->getSurfaceHeapManager();
1697}
1698
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001699int32_t Client::generateId(int pid)
1700{
1701 const uint32_t i = clz( ~mBitmap );
1702 if (i >= NUM_LAYERS_MAX) {
1703 return NO_MEMORY;
1704 }
1705 mPid = pid;
1706 mInUse.add(uint8_t(i));
1707 mBitmap |= 1<<(31-i);
1708 return i;
1709}
1710status_t Client::bindLayer(LayerBaseClient* layer, int32_t id)
1711{
1712 ssize_t idx = mInUse.indexOf(id);
1713 if (idx < 0)
1714 return NAME_NOT_FOUND;
1715 return mLayers.insertAt(layer, idx);
1716}
1717void Client::free(int32_t id)
1718{
1719 ssize_t idx = mInUse.remove(uint8_t(id));
1720 if (idx >= 0) {
1721 mBitmap &= ~(1<<(31-id));
1722 mLayers.removeItemsAt(idx);
1723 }
1724}
1725
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -08001726sp<MemoryDealer> Client::createAllocator(uint32_t flags)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001727{
1728 sp<MemoryDealer> allocator;
The Android Open Source Projecte09fd9e2008-12-17 18:05:43 -08001729 allocator = getSurfaceHeapManager()->createHeap(
1730 flags, getClientPid(), mSharedHeapAllocator);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001731 return allocator;
1732}
1733
1734bool Client::isValid(int32_t i) const {
1735 return (uint32_t(i)<NUM_LAYERS_MAX) && (mBitmap & (1<<(31-i)));
1736}
1737const uint8_t* Client::inUseArray() const {
1738 return mInUse.array();
1739}
1740size_t Client::numActiveLayers() const {
1741 return mInUse.size();
1742}
1743LayerBaseClient* Client::getLayerUser(int32_t i) const {
1744 ssize_t idx = mInUse.indexOf(uint8_t(i));
1745 if (idx<0) return 0;
1746 return mLayers[idx];
1747}
1748
1749void Client::dump(const char* what)
1750{
1751}
1752
1753// ---------------------------------------------------------------------------
1754#if 0
1755#pragma mark -
1756#endif
1757
1758BClient::BClient(SurfaceFlinger *flinger, ClientID cid, const sp<IMemory>& cblk)
1759 : mId(cid), mFlinger(flinger), mCblk(cblk)
1760{
1761}
1762
1763BClient::~BClient() {
1764 // destroy all resources attached to this client
1765 mFlinger->destroyConnection(mId);
1766}
1767
1768void BClient::getControlBlocks(sp<IMemory>* ctrl) const {
1769 *ctrl = mCblk;
1770}
1771
1772sp<ISurface> BClient::createSurface(
1773 ISurfaceFlingerClient::surface_data_t* params, int pid,
1774 DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
1775 uint32_t flags)
1776{
1777 return mFlinger->createSurface(mId, pid, params, display, w, h, format, flags);
1778}
1779
1780status_t BClient::destroySurface(SurfaceID sid)
1781{
1782 sid |= (mId << 16); // add the client-part to id
1783 return mFlinger->destroySurface(sid);
1784}
1785
1786status_t BClient::setState(int32_t count, const layer_state_t* states)
1787{
1788 return mFlinger->setClientState(mId, count, states);
1789}
1790
1791// ---------------------------------------------------------------------------
1792
1793GraphicPlane::GraphicPlane()
1794 : mHw(0)
1795{
1796}
1797
1798GraphicPlane::~GraphicPlane() {
1799 delete mHw;
1800}
1801
1802bool GraphicPlane::initialized() const {
1803 return mHw ? true : false;
1804}
1805
1806void GraphicPlane::setDisplayHardware(DisplayHardware *hw) {
1807 mHw = hw;
1808}
1809
1810void GraphicPlane::setTransform(const Transform& tr) {
1811 mTransform = tr;
1812 mGlobalTransform = mOrientationTransform * mTransform;
1813}
1814
1815status_t GraphicPlane::setOrientation(int orientation)
1816{
1817 float a, b, c, d, x, y;
1818
1819 const DisplayHardware& hw(displayHardware());
1820 const float w = hw.getWidth();
1821 const float h = hw.getHeight();
1822
1823 if (orientation == ISurfaceComposer::eOrientationDefault) {
1824 // make sure the default orientation is optimal
1825 mOrientationTransform.reset();
1826 mGlobalTransform = mTransform;
1827 return NO_ERROR;
1828 }
1829
1830 // If the rotation can be handled in hardware, this is where
1831 // the magic should happen.
1832
1833 switch (orientation) {
1834 case ISurfaceComposer::eOrientation90:
1835 a=0; b=-1; c=1; d=0; x=w; y=0;
1836 break;
1837 case ISurfaceComposer::eOrientation180:
1838 a=-1; b=0; c=0; d=-1; x=w; y=h;
1839 break;
1840 case ISurfaceComposer::eOrientation270:
1841 a=0; b=1; c=-1; d=0; x=0; y=h;
1842 break;
1843 case 42: {
1844 const float r = (3.14159265f / 180.0f) * 42.0f;
1845 const float si = sinf(r);
1846 const float co = cosf(r);
1847 a=co; b=-si; c=si; d=co;
1848 x = si*(h*0.5f) + (1-co)*(w*0.5f);
1849 y =-si*(w*0.5f) + (1-co)*(h*0.5f);
1850 } break;
1851 default:
1852 return BAD_VALUE;
1853 }
1854 mOrientationTransform.set(a, b, c, d);
1855 mOrientationTransform.set(x, y);
1856 mGlobalTransform = mOrientationTransform * mTransform;
1857 return NO_ERROR;
1858}
1859
1860const DisplayHardware& GraphicPlane::displayHardware() const {
1861 return *mHw;
1862}
1863
1864const Transform& GraphicPlane::transform() const {
1865 return mGlobalTransform;
1866}
1867
1868// ---------------------------------------------------------------------------
1869
1870}; // namespace android