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