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