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