blob: fb256638cd7164728b48c8e6ce761e15873f969d [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.
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->contentDirty) {
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->contentDirty = false;
773 } else {
Mathias Agopian6b3287b2009-06-28 02:54:16 -0700774 /* compute the exposed region:
775 * exposed = what's VISIBLE and NOT COVERED now
776 * but was COVERED before
777 */
778 dirty = (visibleRegion - coveredRegion) & layer->coveredRegionScreen;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800779 }
780 dirty.subtractSelf(aboveOpaqueLayers);
781
782 // accumulate to the screen dirty region
783 dirtyRegion.orSelf(dirty);
784
785 // updade aboveOpaqueLayers/aboveCoveredLayers for next (lower) layer
786 aboveOpaqueLayers.orSelf(opaqueRegion);
Mathias Agopian6b3287b2009-06-28 02:54:16 -0700787 aboveCoveredLayers.orSelf(visibleRegion);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800788
789 // Store the visible region is screen space
790 layer->setVisibleRegion(visibleRegion);
791 layer->setCoveredRegion(coveredRegion);
792
793 // If a secure layer is partially visible, lockdown the screen!
794 if (layer->isSecure() && !visibleRegion.isEmpty()) {
795 secureFrameBuffer = true;
796 }
797 }
798
799 mSecureFrameBuffer = secureFrameBuffer;
800 opaqueRegion = aboveOpaqueLayers;
801}
802
803
804void SurfaceFlinger::commitTransaction()
805{
806 mDrawingState = mCurrentState;
807 mTransactionCV.signal();
808}
809
810void SurfaceFlinger::handlePageFlip()
811{
812 bool visibleRegions = mVisibleRegionsDirty;
813 LayerVector& currentLayers = const_cast<LayerVector&>(mDrawingState.layersSortedByZ);
814 visibleRegions |= lockPageFlip(currentLayers);
815
816 const DisplayHardware& hw = graphicPlane(0).displayHardware();
817 const Region screenRegion(hw.bounds());
818 if (visibleRegions) {
819 Region opaqueRegion;
820 computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion);
821 mWormholeRegion = screenRegion.subtract(opaqueRegion);
822 mVisibleRegionsDirty = false;
823 }
824
825 unlockPageFlip(currentLayers);
826 mDirtyRegion.andSelf(screenRegion);
827}
828
829bool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers)
830{
831 bool recomputeVisibleRegions = false;
832 size_t count = currentLayers.size();
833 LayerBase* const* layers = currentLayers.array();
834 for (size_t i=0 ; i<count ; i++) {
835 LayerBase* const layer = layers[i];
836 layer->lockPageFlip(recomputeVisibleRegions);
837 }
838 return recomputeVisibleRegions;
839}
840
841void SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
842{
843 const GraphicPlane& plane(graphicPlane(0));
844 const Transform& planeTransform(plane.transform());
845 size_t count = currentLayers.size();
846 LayerBase* const* layers = currentLayers.array();
847 for (size_t i=0 ; i<count ; i++) {
848 LayerBase* const layer = layers[i];
849 layer->unlockPageFlip(planeTransform, mDirtyRegion);
850 }
851}
852
853void SurfaceFlinger::handleRepaint()
854{
855 // set the frame buffer
856 const DisplayHardware& hw(graphicPlane(0).displayHardware());
857 glMatrixMode(GL_MODELVIEW);
858 glLoadIdentity();
859
860 if (UNLIKELY(mDebugRegion)) {
861 debugFlashRegions();
862 }
863
864 // compute the invalid region
865 mInvalidRegion.orSelf(mDirtyRegion);
866
867 uint32_t flags = hw.getFlags();
868 if (flags & DisplayHardware::BUFFER_PRESERVED) {
869 // here we assume DisplayHardware::flip()'s implementation
870 // performs the copy-back optimization.
871 } else {
872 if (flags & DisplayHardware::UPDATE_ON_DEMAND) {
873 // we need to fully redraw the part that will be updated
874 mDirtyRegion.set(mInvalidRegion.bounds());
875 } else {
876 // we need to redraw everything
877 mDirtyRegion.set(hw.bounds());
878 mInvalidRegion = mDirtyRegion;
879 }
880 }
881
882 // compose all surfaces
883 composeSurfaces(mDirtyRegion);
884
885 // clear the dirty regions
886 mDirtyRegion.clear();
887}
888
889void SurfaceFlinger::composeSurfaces(const Region& dirty)
890{
891 if (UNLIKELY(!mWormholeRegion.isEmpty())) {
892 // should never happen unless the window manager has a bug
893 // draw something...
894 drawWormhole();
895 }
896 const SurfaceFlinger& flinger(*this);
897 const LayerVector& drawingLayers(mDrawingState.layersSortedByZ);
898 const size_t count = drawingLayers.size();
899 LayerBase const* const* const layers = drawingLayers.array();
900 for (size_t i=0 ; i<count ; ++i) {
901 LayerBase const * const layer = layers[i];
902 const Region& visibleRegion(layer->visibleRegionScreen);
903 if (!visibleRegion.isEmpty()) {
904 const Region clip(dirty.intersect(visibleRegion));
905 if (!clip.isEmpty()) {
906 layer->draw(clip);
907 }
908 }
909 }
910}
911
912void SurfaceFlinger::unlockClients()
913{
914 const LayerVector& drawingLayers(mDrawingState.layersSortedByZ);
915 const size_t count = drawingLayers.size();
916 LayerBase* const* const layers = drawingLayers.array();
917 for (size_t i=0 ; i<count ; ++i) {
918 LayerBase* const layer = layers[i];
919 layer->finishPageFlip();
920 }
921}
922
923void SurfaceFlinger::scheduleBroadcast(Client* client)
924{
925 if (mLastScheduledBroadcast != client) {
926 mLastScheduledBroadcast = client;
927 mScheduledBroadcasts.add(client);
928 }
929}
930
931void SurfaceFlinger::executeScheduledBroadcasts()
932{
933 SortedVector<Client*>& list = mScheduledBroadcasts;
934 size_t count = list.size();
935 while (count--) {
936 per_client_cblk_t* const cblk = list[count]->ctrlblk;
937 if (cblk->lock.tryLock() == NO_ERROR) {
938 cblk->cv.broadcast();
939 list.removeAt(count);
940 cblk->lock.unlock();
941 } else {
942 // schedule another round
943 LOGW("executeScheduledBroadcasts() skipped, "
944 "contention on the client. We'll try again later...");
945 signalDelayedEvent(ms2ns(4));
946 }
947 }
948 mLastScheduledBroadcast = 0;
949}
950
951void SurfaceFlinger::handleDebugCpu()
952{
953 Mutex::Autolock _l(mDebugLock);
954 if (mCpuGauge != 0)
955 mCpuGauge->sample();
956}
957
958void SurfaceFlinger::debugFlashRegions()
959{
960 if (UNLIKELY(!mDirtyRegion.isRect())) {
961 // TODO: do this only if we don't have preserving
962 // swapBuffer. If we don't have update-on-demand,
963 // redraw everything.
964 composeSurfaces(Region(mDirtyRegion.bounds()));
965 }
966
967 glDisable(GL_TEXTURE_2D);
968 glDisable(GL_BLEND);
969 glDisable(GL_DITHER);
970 glDisable(GL_SCISSOR_TEST);
971
972 glColor4x(0x10000, 0, 0x10000, 0x10000);
973
974 Rect r;
975 Region::iterator iterator(mDirtyRegion);
976 while (iterator.iterate(&r)) {
977 GLfloat vertices[][2] = {
978 { r.left, r.top },
979 { r.left, r.bottom },
980 { r.right, r.bottom },
981 { r.right, r.top }
982 };
983 glVertexPointer(2, GL_FLOAT, 0, vertices);
984 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
985 }
986
987 const DisplayHardware& hw(graphicPlane(0).displayHardware());
988 hw.flip(mDirtyRegion.merge(mInvalidRegion));
989 mInvalidRegion.clear();
990
991 if (mDebugRegion > 1)
992 usleep(mDebugRegion * 1000);
993
994 glEnable(GL_SCISSOR_TEST);
995 //mDirtyRegion.dump("mDirtyRegion");
996}
997
998void SurfaceFlinger::drawWormhole() const
999{
1000 const Region region(mWormholeRegion.intersect(mDirtyRegion));
1001 if (region.isEmpty())
1002 return;
1003
1004 const DisplayHardware& hw(graphicPlane(0).displayHardware());
1005 const int32_t width = hw.getWidth();
1006 const int32_t height = hw.getHeight();
1007
1008 glDisable(GL_BLEND);
1009 glDisable(GL_DITHER);
1010
1011 if (LIKELY(!mDebugBackground)) {
1012 glClearColorx(0,0,0,0);
1013 Rect r;
1014 Region::iterator iterator(region);
1015 while (iterator.iterate(&r)) {
1016 const GLint sy = height - (r.top + r.height());
1017 glScissor(r.left, sy, r.width(), r.height());
1018 glClear(GL_COLOR_BUFFER_BIT);
1019 }
1020 } else {
1021 const GLshort vertices[][2] = { { 0, 0 }, { width, 0 },
1022 { width, height }, { 0, height } };
1023 const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 }, { 1, 1 }, { 0, 1 } };
1024 glVertexPointer(2, GL_SHORT, 0, vertices);
1025 glTexCoordPointer(2, GL_SHORT, 0, tcoords);
1026 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1027 glEnable(GL_TEXTURE_2D);
1028 glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
1029 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1030 glMatrixMode(GL_TEXTURE);
1031 glLoadIdentity();
1032 glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1);
1033 Rect r;
1034 Region::iterator iterator(region);
1035 while (iterator.iterate(&r)) {
1036 const GLint sy = height - (r.top + r.height());
1037 glScissor(r.left, sy, r.width(), r.height());
1038 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1039 }
1040 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1041 }
1042}
1043
1044void SurfaceFlinger::debugShowFPS() const
1045{
1046 static int mFrameCount;
1047 static int mLastFrameCount = 0;
1048 static nsecs_t mLastFpsTime = 0;
1049 static float mFps = 0;
1050 mFrameCount++;
1051 nsecs_t now = systemTime();
1052 nsecs_t diff = now - mLastFpsTime;
1053 if (diff > ms2ns(250)) {
1054 mFps = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
1055 mLastFpsTime = now;
1056 mLastFrameCount = mFrameCount;
1057 }
1058 // XXX: mFPS has the value we want
1059 }
1060
1061status_t SurfaceFlinger::addLayer(LayerBase* layer)
1062{
1063 Mutex::Autolock _l(mStateLock);
1064 addLayer_l(layer);
1065 setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
1066 return NO_ERROR;
1067}
1068
1069status_t SurfaceFlinger::removeLayer(LayerBase* layer)
1070{
1071 Mutex::Autolock _l(mStateLock);
1072 removeLayer_l(layer);
1073 setTransactionFlags(eTransactionNeeded);
1074 return NO_ERROR;
1075}
1076
1077status_t SurfaceFlinger::invalidateLayerVisibility(LayerBase* layer)
1078{
1079 layer->forceVisibilityTransaction();
1080 setTransactionFlags(eTraversalNeeded);
1081 return NO_ERROR;
1082}
1083
1084status_t SurfaceFlinger::addLayer_l(LayerBase* layer)
1085{
1086 ssize_t i = mCurrentState.layersSortedByZ.add(
1087 layer, &LayerBase::compareCurrentStateZ);
1088 LayerBaseClient* lbc = LayerBase::dynamicCast<LayerBaseClient*>(layer);
1089 if (lbc) {
1090 mLayerMap.add(lbc->serverIndex(), lbc);
1091 }
1092 mRemovedLayers.remove(layer);
1093 return NO_ERROR;
1094}
1095
1096status_t SurfaceFlinger::removeLayer_l(LayerBase* layerBase)
1097{
1098 ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
1099 if (index >= 0) {
1100 mRemovedLayers.add(layerBase);
1101 LayerBaseClient* layer = LayerBase::dynamicCast<LayerBaseClient*>(layerBase);
1102 if (layer) {
1103 mLayerMap.removeItem(layer->serverIndex());
1104 }
1105 return NO_ERROR;
1106 }
1107 // it's possible that we don't find a layer, because it might
1108 // have been destroyed already -- this is not technically an error
1109 // from the user because there is a race between destroySurface,
1110 // destroyclient and destroySurface-from-a-transaction.
1111 return (index == NAME_NOT_FOUND) ? status_t(NO_ERROR) : index;
1112}
1113
1114void SurfaceFlinger::free_resources_l()
1115{
1116 // Destroy layers that were removed
1117 destroy_all_removed_layers_l();
1118
1119 // free resources associated with disconnected clients
1120 SortedVector<Client*>& scheduledBroadcasts(mScheduledBroadcasts);
1121 Vector<Client*>& disconnectedClients(mDisconnectedClients);
1122 const size_t count = disconnectedClients.size();
1123 for (size_t i=0 ; i<count ; i++) {
1124 Client* client = disconnectedClients[i];
1125 // if this client is the scheduled broadcast list,
1126 // remove it from there (and we don't need to signal it
1127 // since it is dead).
1128 int32_t index = scheduledBroadcasts.indexOf(client);
1129 if (index >= 0) {
1130 scheduledBroadcasts.removeItemsAt(index);
1131 }
1132 mTokens.release(client->cid);
1133 delete client;
1134 }
1135 disconnectedClients.clear();
1136}
1137
1138void SurfaceFlinger::destroy_all_removed_layers_l()
1139{
1140 size_t c = mRemovedLayers.size();
1141 while (c--) {
1142 LayerBase* const removed_layer = mRemovedLayers[c];
1143
1144 LOGE_IF(mCurrentState.layersSortedByZ.indexOf(removed_layer) >= 0,
1145 "layer %p removed but still in the current state list",
1146 removed_layer);
1147
1148 delete removed_layer;
1149 }
1150 mRemovedLayers.clear();
1151}
1152
1153
1154uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
1155{
1156 return android_atomic_and(~flags, &mTransactionFlags) & flags;
1157}
1158
1159uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags, nsecs_t delay)
1160{
1161 uint32_t old = android_atomic_or(flags, &mTransactionFlags);
1162 if ((old & flags)==0) { // wake the server up
1163 if (delay > 0) {
1164 signalDelayedEvent(delay);
1165 } else {
1166 signalEvent();
1167 }
1168 }
1169 return old;
1170}
1171
1172void SurfaceFlinger::openGlobalTransaction()
1173{
1174 android_atomic_inc(&mTransactionCount);
1175}
1176
1177void SurfaceFlinger::closeGlobalTransaction()
1178{
1179 if (android_atomic_dec(&mTransactionCount) == 1) {
1180 signalEvent();
1181 }
1182}
1183
1184status_t SurfaceFlinger::freezeDisplay(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 = 1;
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
1198status_t SurfaceFlinger::unfreezeDisplay(DisplayID dpy, uint32_t flags)
1199{
1200 if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1201 return BAD_VALUE;
1202
1203 Mutex::Autolock _l(mStateLock);
1204 mCurrentState.freezeDisplay = 0;
1205 setTransactionFlags(eTransactionNeeded);
1206
1207 // flags is intended to communicate some sort of animation behavior
1208 // (for instance fadding)
1209 return NO_ERROR;
1210}
1211
Mathias Agopian24fd77d2009-03-27 16:10:37 -07001212int SurfaceFlinger::setOrientation(DisplayID dpy,
1213 int orientation, uint32_t flags)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001214{
1215 if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
1216 return BAD_VALUE;
1217
1218 Mutex::Autolock _l(mStateLock);
1219 if (mCurrentState.orientation != orientation) {
1220 if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
Mathias Agopian24fd77d2009-03-27 16:10:37 -07001221 mCurrentState.orientationType = flags;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001222 mCurrentState.orientation = orientation;
1223 setTransactionFlags(eTransactionNeeded);
1224 mTransactionCV.wait(mStateLock);
1225 } else {
1226 orientation = BAD_VALUE;
1227 }
1228 }
1229 return orientation;
1230}
1231
1232sp<ISurface> SurfaceFlinger::createSurface(ClientID clientId, int pid,
1233 ISurfaceFlingerClient::surface_data_t* params,
1234 DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
1235 uint32_t flags)
1236{
1237 LayerBaseClient* layer = 0;
1238 sp<LayerBaseClient::Surface> surfaceHandle;
Mathias Agopian6e2d6482009-07-09 18:16:43 -07001239
1240 if (int32_t(w|h) < 0) {
1241 LOGE("createSurface() failed, w or h is negative (w=%d, h=%d)",
1242 int(w), int(h));
1243 return surfaceHandle;
1244 }
1245
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001246 Mutex::Autolock _l(mStateLock);
1247 Client* const c = mClientsMap.valueFor(clientId);
1248 if (UNLIKELY(!c)) {
1249 LOGE("createSurface() failed, client not found (id=%d)", clientId);
1250 return surfaceHandle;
1251 }
1252
1253 //LOGD("createSurface for pid %d (%d x %d)", pid, w, h);
1254 int32_t id = c->generateId(pid);
1255 if (uint32_t(id) >= NUM_LAYERS_MAX) {
1256 LOGE("createSurface() failed, generateId = %d", id);
1257 return surfaceHandle;
1258 }
1259
1260 switch (flags & eFXSurfaceMask) {
1261 case eFXSurfaceNormal:
1262 if (UNLIKELY(flags & ePushBuffers)) {
1263 layer = createPushBuffersSurfaceLocked(c, d, id, w, h, flags);
1264 } else {
1265 layer = createNormalSurfaceLocked(c, d, id, w, h, format, flags);
1266 }
1267 break;
1268 case eFXSurfaceBlur:
1269 layer = createBlurSurfaceLocked(c, d, id, w, h, flags);
1270 break;
1271 case eFXSurfaceDim:
1272 layer = createDimSurfaceLocked(c, d, id, w, h, flags);
1273 break;
1274 }
1275
1276 if (layer) {
1277 setTransactionFlags(eTransactionNeeded);
1278 surfaceHandle = layer->getSurface();
1279 if (surfaceHandle != 0)
1280 surfaceHandle->getSurfaceData(params);
1281 }
1282
1283 return surfaceHandle;
1284}
1285
1286LayerBaseClient* SurfaceFlinger::createNormalSurfaceLocked(
1287 Client* client, DisplayID display,
1288 int32_t id, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags)
1289{
1290 // initialize the surfaces
1291 switch (format) { // TODO: take h/w into account
1292 case PIXEL_FORMAT_TRANSPARENT:
1293 case PIXEL_FORMAT_TRANSLUCENT:
1294 format = PIXEL_FORMAT_RGBA_8888;
1295 break;
1296 case PIXEL_FORMAT_OPAQUE:
1297 format = PIXEL_FORMAT_RGB_565;
1298 break;
1299 }
1300
1301 Layer* layer = new Layer(this, display, client, id);
1302 status_t err = layer->setBuffers(client, w, h, format, flags);
1303 if (LIKELY(err == NO_ERROR)) {
1304 layer->initStates(w, h, flags);
1305 addLayer_l(layer);
1306 } else {
1307 LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
1308 delete layer;
1309 return 0;
1310 }
1311 return layer;
1312}
1313
1314LayerBaseClient* SurfaceFlinger::createBlurSurfaceLocked(
1315 Client* client, DisplayID display,
1316 int32_t id, uint32_t w, uint32_t h, uint32_t flags)
1317{
1318 LayerBlur* layer = new LayerBlur(this, display, client, id);
1319 layer->initStates(w, h, flags);
1320 addLayer_l(layer);
1321 return layer;
1322}
1323
1324LayerBaseClient* SurfaceFlinger::createDimSurfaceLocked(
1325 Client* client, DisplayID display,
1326 int32_t id, uint32_t w, uint32_t h, uint32_t flags)
1327{
1328 LayerDim* layer = new LayerDim(this, display, client, id);
1329 layer->initStates(w, h, flags);
1330 addLayer_l(layer);
1331 return layer;
1332}
1333
1334LayerBaseClient* SurfaceFlinger::createPushBuffersSurfaceLocked(
1335 Client* client, DisplayID display,
1336 int32_t id, uint32_t w, uint32_t h, uint32_t flags)
1337{
1338 LayerBuffer* layer = new LayerBuffer(this, display, client, id);
1339 layer->initStates(w, h, flags);
1340 addLayer_l(layer);
1341 return layer;
1342}
1343
1344status_t SurfaceFlinger::destroySurface(SurfaceID index)
1345{
1346 Mutex::Autolock _l(mStateLock);
1347 LayerBaseClient* const layer = getLayerUser_l(index);
1348 status_t err = removeLayer_l(layer);
1349 if (err < 0)
1350 return err;
1351 setTransactionFlags(eTransactionNeeded);
1352 return NO_ERROR;
1353}
1354
1355status_t SurfaceFlinger::setClientState(
1356 ClientID cid,
1357 int32_t count,
1358 const layer_state_t* states)
1359{
1360 Mutex::Autolock _l(mStateLock);
1361 uint32_t flags = 0;
1362 cid <<= 16;
1363 for (int i=0 ; i<count ; i++) {
1364 const layer_state_t& s = states[i];
1365 LayerBaseClient* layer = getLayerUser_l(s.surface | cid);
1366 if (layer) {
1367 const uint32_t what = s.what;
1368 // check if it has been destroyed first
1369 if (what & eDestroyed) {
1370 if (removeLayer_l(layer) == NO_ERROR) {
1371 flags |= eTransactionNeeded;
1372 // we skip everything else... well, no, not really
1373 // we skip ONLY that transaction.
1374 continue;
1375 }
1376 }
1377 if (what & ePositionChanged) {
1378 if (layer->setPosition(s.x, s.y))
1379 flags |= eTraversalNeeded;
1380 }
1381 if (what & eLayerChanged) {
1382 if (layer->setLayer(s.z)) {
1383 mCurrentState.layersSortedByZ.reorder(
1384 layer, &Layer::compareCurrentStateZ);
1385 // we need traversal (state changed)
1386 // AND transaction (list changed)
1387 flags |= eTransactionNeeded|eTraversalNeeded;
1388 }
1389 }
1390 if (what & eSizeChanged) {
1391 if (layer->setSize(s.w, s.h))
1392 flags |= eTraversalNeeded;
1393 }
1394 if (what & eAlphaChanged) {
1395 if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
1396 flags |= eTraversalNeeded;
1397 }
1398 if (what & eMatrixChanged) {
1399 if (layer->setMatrix(s.matrix))
1400 flags |= eTraversalNeeded;
1401 }
1402 if (what & eTransparentRegionChanged) {
1403 if (layer->setTransparentRegionHint(s.transparentRegion))
1404 flags |= eTraversalNeeded;
1405 }
1406 if (what & eVisibilityChanged) {
1407 if (layer->setFlags(s.flags, s.mask))
1408 flags |= eTraversalNeeded;
1409 }
1410 }
1411 }
1412 if (flags) {
1413 setTransactionFlags(flags);
1414 }
1415 return NO_ERROR;
1416}
1417
1418LayerBaseClient* SurfaceFlinger::getLayerUser_l(SurfaceID s) const
1419{
1420 return mLayerMap.valueFor(s);
1421}
1422
1423void SurfaceFlinger::screenReleased(int dpy)
1424{
1425 // this may be called by a signal handler, we can't do too much in here
1426 android_atomic_or(eConsoleReleased, &mConsoleSignals);
1427 signalEvent();
1428}
1429
1430void SurfaceFlinger::screenAcquired(int dpy)
1431{
1432 // this may be called by a signal handler, we can't do too much in here
1433 android_atomic_or(eConsoleAcquired, &mConsoleSignals);
1434 signalEvent();
1435}
1436
1437status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
1438{
1439 const size_t SIZE = 1024;
1440 char buffer[SIZE];
1441 String8 result;
1442 if (checkCallingPermission(
1443 String16("android.permission.DUMP")) == false)
1444 { // not allowed
1445 snprintf(buffer, SIZE, "Permission Denial: "
1446 "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
1447 IPCThreadState::self()->getCallingPid(),
1448 IPCThreadState::self()->getCallingUid());
1449 result.append(buffer);
1450 } else {
1451 Mutex::Autolock _l(mStateLock);
1452 size_t s = mClientsMap.size();
1453 char name[64];
1454 for (size_t i=0 ; i<s ; i++) {
1455 Client* client = mClientsMap.valueAt(i);
1456 sprintf(name, " Client (id=0x%08x)", client->cid);
1457 client->dump(name);
1458 }
1459 const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
1460 const size_t count = currentLayers.size();
1461 for (size_t i=0 ; i<count ; i++) {
1462 /*** LayerBase ***/
1463 LayerBase const * const layer = currentLayers[i];
1464 const Layer::State& s = layer->drawingState();
1465 snprintf(buffer, SIZE,
1466 "+ %s %p\n"
1467 " "
1468 "z=%9d, pos=(%4d,%4d), size=(%4d,%4d), "
1469 "needsBlending=%1d, invalidate=%1d, "
1470 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n",
1471 layer->getTypeID(), layer,
1472 s.z, layer->tx(), layer->ty(), s.w, s.h,
1473 layer->needsBlending(), layer->contentDirty,
1474 s.alpha, s.flags,
1475 s.transform[0], s.transform[1],
1476 s.transform[2], s.transform[3]);
1477 result.append(buffer);
1478 buffer[0] = 0;
1479 /*** LayerBaseClient ***/
1480 LayerBaseClient* const lbc =
1481 LayerBase::dynamicCast<LayerBaseClient*>((LayerBase*)layer);
1482 if (lbc) {
1483 snprintf(buffer, SIZE,
1484 " "
1485 "id=0x%08x, client=0x%08x, identity=%u\n",
1486 lbc->clientIndex(), lbc->client ? lbc->client->cid : 0,
1487 lbc->getIdentity());
1488 }
1489 result.append(buffer);
1490 buffer[0] = 0;
1491 /*** Layer ***/
1492 Layer* const l = LayerBase::dynamicCast<Layer*>((LayerBase*)layer);
1493 if (l) {
1494 const LayerBitmap& buf0(l->getBuffer(0));
1495 const LayerBitmap& buf1(l->getBuffer(1));
1496 snprintf(buffer, SIZE,
1497 " "
1498 "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u], mTextureName=%d,"
1499 " freezeLock=%p, swapState=0x%08x\n",
1500 l->pixelFormat(),
1501 buf0.width(), buf0.height(), buf0.stride(),
1502 buf1.width(), buf1.height(), buf1.stride(),
1503 l->getTextureName(), l->getFreezeLock().get(),
1504 l->lcblk->swapState);
1505 }
1506 result.append(buffer);
1507 buffer[0] = 0;
1508 s.transparentRegion.dump(result, "transparentRegion");
1509 layer->transparentRegionScreen.dump(result, "transparentRegionScreen");
1510 layer->visibleRegionScreen.dump(result, "visibleRegionScreen");
1511 }
1512 mWormholeRegion.dump(result, "WormholeRegion");
1513 const DisplayHardware& hw(graphicPlane(0).displayHardware());
1514 snprintf(buffer, SIZE,
1515 " display frozen: %s, freezeCount=%d, orientation=%d, canDraw=%d\n",
1516 mFreezeDisplay?"yes":"no", mFreezeCount,
1517 mCurrentState.orientation, hw.canDraw());
1518 result.append(buffer);
1519
1520 sp<AllocatorInterface> allocator;
1521 if (mGPU != 0) {
1522 snprintf(buffer, SIZE, " GPU owner: %d\n", mGPU->getOwner());
1523 result.append(buffer);
1524 allocator = mGPU->getAllocator();
1525 if (allocator != 0) {
1526 allocator->dump(result, "GPU Allocator");
1527 }
1528 }
1529 allocator = mSurfaceHeapManager->getAllocator(NATIVE_MEMORY_TYPE_PMEM);
1530 if (allocator != 0) {
1531 allocator->dump(result, "PMEM Allocator");
1532 }
1533 }
1534 write(fd, result.string(), result.size());
1535 return NO_ERROR;
1536}
1537
1538status_t SurfaceFlinger::onTransact(
1539 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1540{
1541 switch (code) {
1542 case CREATE_CONNECTION:
1543 case OPEN_GLOBAL_TRANSACTION:
1544 case CLOSE_GLOBAL_TRANSACTION:
1545 case SET_ORIENTATION:
1546 case FREEZE_DISPLAY:
1547 case UNFREEZE_DISPLAY:
1548 case BOOT_FINISHED:
1549 case REVOKE_GPU:
1550 {
1551 // codes that require permission check
1552 IPCThreadState* ipc = IPCThreadState::self();
1553 const int pid = ipc->getCallingPid();
Mathias Agopiana1ecca92009-05-21 19:21:59 -07001554 const int uid = ipc->getCallingUid();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001555 const int self_pid = getpid();
Mathias Agopiana1ecca92009-05-21 19:21:59 -07001556 if (UNLIKELY(pid != self_pid && uid != AID_GRAPHICS)) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001557 // we're called from a different process, do the real check
1558 if (!checkCallingPermission(
1559 String16("android.permission.ACCESS_SURFACE_FLINGER")))
1560 {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001561 LOGE("Permission Denial: "
1562 "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
1563 return PERMISSION_DENIED;
1564 }
1565 }
1566 }
1567 }
1568
1569 status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
1570 if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
1571 // HARDWARE_TEST stuff...
1572 if (UNLIKELY(checkCallingPermission(
1573 String16("android.permission.HARDWARE_TEST")) == false))
1574 { // not allowed
1575 LOGE("Permission Denial: pid=%d, uid=%d\n",
1576 IPCThreadState::self()->getCallingPid(),
1577 IPCThreadState::self()->getCallingUid());
1578 return PERMISSION_DENIED;
1579 }
1580 int n;
1581 switch (code) {
1582 case 1000: // SHOW_CPU
1583 n = data.readInt32();
1584 mDebugCpu = n ? 1 : 0;
1585 if (mDebugCpu) {
1586 if (mCpuGauge == 0) {
1587 mCpuGauge = new CPUGauge(this, ms2ns(500));
1588 }
1589 } else {
1590 if (mCpuGauge != 0) {
1591 mCpuGauge->requestExitAndWait();
1592 Mutex::Autolock _l(mDebugLock);
1593 mCpuGauge.clear();
1594 }
1595 }
1596 return NO_ERROR;
1597 case 1001: // SHOW_FPS
1598 n = data.readInt32();
1599 mDebugFps = n ? 1 : 0;
1600 return NO_ERROR;
1601 case 1002: // SHOW_UPDATES
1602 n = data.readInt32();
1603 mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
1604 return NO_ERROR;
1605 case 1003: // SHOW_BACKGROUND
1606 n = data.readInt32();
1607 mDebugBackground = n ? 1 : 0;
1608 return NO_ERROR;
1609 case 1004:{ // repaint everything
1610 Mutex::Autolock _l(mStateLock);
1611 const DisplayHardware& hw(graphicPlane(0).displayHardware());
1612 mDirtyRegion.set(hw.bounds()); // careful that's not thread-safe
1613 signalEvent();
1614 }
1615 return NO_ERROR;
1616 case 1005: // ask GPU revoke
Mathias Agopian2b42fa72009-04-27 18:50:06 -07001617 if (mGPU != 0) {
1618 mGPU->friendlyRevoke();
1619 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001620 return NO_ERROR;
1621 case 1006: // revoke GPU
Mathias Agopian2b42fa72009-04-27 18:50:06 -07001622 if (mGPU != 0) {
1623 mGPU->unconditionalRevoke();
1624 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001625 return NO_ERROR;
1626 case 1007: // set mFreezeCount
1627 mFreezeCount = data.readInt32();
1628 return NO_ERROR;
1629 case 1010: // interrogate.
1630 reply->writeInt32(mDebugCpu);
1631 reply->writeInt32(0);
1632 reply->writeInt32(mDebugRegion);
1633 reply->writeInt32(mDebugBackground);
1634 return NO_ERROR;
1635 case 1013: {
1636 Mutex::Autolock _l(mStateLock);
1637 const DisplayHardware& hw(graphicPlane(0).displayHardware());
1638 reply->writeInt32(hw.getPageFlipCount());
1639 }
1640 return NO_ERROR;
1641 }
1642 }
1643 return err;
1644}
1645
1646// ---------------------------------------------------------------------------
1647#if 0
1648#pragma mark -
1649#endif
1650
1651Client::Client(ClientID clientID, const sp<SurfaceFlinger>& flinger)
1652 : ctrlblk(0), cid(clientID), mPid(0), mBitmap(0), mFlinger(flinger)
1653{
1654 mSharedHeapAllocator = getSurfaceHeapManager()->createHeap();
1655 const int pgsize = getpagesize();
1656 const int cblksize=((sizeof(per_client_cblk_t)+(pgsize-1))&~(pgsize-1));
1657 mCblkHeap = new MemoryDealer(cblksize);
1658 mCblkMemory = mCblkHeap->allocate(cblksize);
1659 if (mCblkMemory != 0) {
1660 ctrlblk = static_cast<per_client_cblk_t *>(mCblkMemory->pointer());
1661 if (ctrlblk) { // construct the shared structure in-place.
1662 new(ctrlblk) per_client_cblk_t;
1663 }
1664 }
1665}
1666
1667Client::~Client() {
1668 if (ctrlblk) {
1669 const int pgsize = getpagesize();
1670 ctrlblk->~per_client_cblk_t(); // destroy our shared-structure.
1671 }
1672}
1673
1674const sp<SurfaceHeapManager>& Client::getSurfaceHeapManager() const {
1675 return mFlinger->getSurfaceHeapManager();
1676}
1677
1678int32_t Client::generateId(int pid)
1679{
1680 const uint32_t i = clz( ~mBitmap );
1681 if (i >= NUM_LAYERS_MAX) {
1682 return NO_MEMORY;
1683 }
1684 mPid = pid;
1685 mInUse.add(uint8_t(i));
1686 mBitmap |= 1<<(31-i);
1687 return i;
1688}
1689status_t Client::bindLayer(LayerBaseClient* layer, int32_t id)
1690{
1691 ssize_t idx = mInUse.indexOf(id);
1692 if (idx < 0)
1693 return NAME_NOT_FOUND;
1694 return mLayers.insertAt(layer, idx);
1695}
1696void Client::free(int32_t id)
1697{
1698 ssize_t idx = mInUse.remove(uint8_t(id));
1699 if (idx >= 0) {
1700 mBitmap &= ~(1<<(31-id));
1701 mLayers.removeItemsAt(idx);
1702 }
1703}
1704
1705sp<MemoryDealer> Client::createAllocator(uint32_t flags)
1706{
1707 sp<MemoryDealer> allocator;
1708 allocator = getSurfaceHeapManager()->createHeap(
1709 flags, getClientPid(), mSharedHeapAllocator);
1710 return allocator;
1711}
1712
1713bool Client::isValid(int32_t i) const {
1714 return (uint32_t(i)<NUM_LAYERS_MAX) && (mBitmap & (1<<(31-i)));
1715}
1716const uint8_t* Client::inUseArray() const {
1717 return mInUse.array();
1718}
1719size_t Client::numActiveLayers() const {
1720 return mInUse.size();
1721}
1722LayerBaseClient* Client::getLayerUser(int32_t i) const {
1723 ssize_t idx = mInUse.indexOf(uint8_t(i));
1724 if (idx<0) return 0;
1725 return mLayers[idx];
1726}
1727
1728void Client::dump(const char* what)
1729{
1730}
1731
1732// ---------------------------------------------------------------------------
1733#if 0
1734#pragma mark -
1735#endif
1736
1737BClient::BClient(SurfaceFlinger *flinger, ClientID cid, const sp<IMemory>& cblk)
1738 : mId(cid), mFlinger(flinger), mCblk(cblk)
1739{
1740}
1741
1742BClient::~BClient() {
1743 // destroy all resources attached to this client
1744 mFlinger->destroyConnection(mId);
1745}
1746
1747void BClient::getControlBlocks(sp<IMemory>* ctrl) const {
1748 *ctrl = mCblk;
1749}
1750
1751sp<ISurface> BClient::createSurface(
1752 ISurfaceFlingerClient::surface_data_t* params, int pid,
1753 DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
1754 uint32_t flags)
1755{
1756 return mFlinger->createSurface(mId, pid, params, display, w, h, format, flags);
1757}
1758
1759status_t BClient::destroySurface(SurfaceID sid)
1760{
1761 sid |= (mId << 16); // add the client-part to id
1762 return mFlinger->destroySurface(sid);
1763}
1764
1765status_t BClient::setState(int32_t count, const layer_state_t* states)
1766{
1767 return mFlinger->setClientState(mId, count, states);
1768}
1769
1770// ---------------------------------------------------------------------------
1771
1772GraphicPlane::GraphicPlane()
1773 : mHw(0)
1774{
1775}
1776
1777GraphicPlane::~GraphicPlane() {
1778 delete mHw;
1779}
1780
1781bool GraphicPlane::initialized() const {
1782 return mHw ? true : false;
1783}
1784
1785void GraphicPlane::setDisplayHardware(DisplayHardware *hw) {
1786 mHw = hw;
1787}
1788
1789void GraphicPlane::setTransform(const Transform& tr) {
1790 mTransform = tr;
1791 mGlobalTransform = mOrientationTransform * mTransform;
1792}
1793
1794status_t GraphicPlane::orientationToTransfrom(
1795 int orientation, int w, int h, Transform* tr)
1796{
1797 float a, b, c, d, x, y;
1798 switch (orientation) {
1799 case ISurfaceComposer::eOrientationDefault:
1800 a=1; b=0; c=0; d=1; x=0; y=0;
1801 break;
1802 case ISurfaceComposer::eOrientation90:
1803 a=0; b=-1; c=1; d=0; x=w; y=0;
1804 break;
1805 case ISurfaceComposer::eOrientation180:
1806 a=-1; b=0; c=0; d=-1; x=w; y=h;
1807 break;
1808 case ISurfaceComposer::eOrientation270:
1809 a=0; b=1; c=-1; d=0; x=0; y=h;
1810 break;
1811 default:
1812 return BAD_VALUE;
1813 }
1814 tr->set(a, b, c, d);
1815 tr->set(x, y);
1816 return NO_ERROR;
1817}
1818
1819status_t GraphicPlane::setOrientation(int orientation)
1820{
1821 const DisplayHardware& hw(displayHardware());
1822 const float w = hw.getWidth();
1823 const float h = hw.getHeight();
1824
1825 if (orientation == ISurfaceComposer::eOrientationDefault) {
1826 // make sure the default orientation is optimal
1827 mOrientationTransform.reset();
Mathias Agopianecbeaa02009-03-27 15:36:09 -07001828 mOrientation = orientation;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001829 mGlobalTransform = mTransform;
1830 return NO_ERROR;
1831 }
1832
1833 // If the rotation can be handled in hardware, this is where
1834 // the magic should happen.
1835 if (UNLIKELY(orientation == 42)) {
1836 float a, b, c, d, x, y;
1837 const float r = (3.14159265f / 180.0f) * 42.0f;
1838 const float si = sinf(r);
1839 const float co = cosf(r);
1840 a=co; b=-si; c=si; d=co;
1841 x = si*(h*0.5f) + (1-co)*(w*0.5f);
1842 y =-si*(w*0.5f) + (1-co)*(h*0.5f);
1843 mOrientationTransform.set(a, b, c, d);
1844 mOrientationTransform.set(x, y);
1845 } else {
1846 GraphicPlane::orientationToTransfrom(orientation, w, h,
1847 &mOrientationTransform);
1848 }
Mathias Agopianecbeaa02009-03-27 15:36:09 -07001849 mOrientation = orientation;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001850 mGlobalTransform = mOrientationTransform * mTransform;
1851 return NO_ERROR;
1852}
1853
1854const DisplayHardware& GraphicPlane::displayHardware() const {
1855 return *mHw;
1856}
1857
1858const Transform& GraphicPlane::transform() const {
1859 return mGlobalTransform;
1860}
1861
1862// ---------------------------------------------------------------------------
1863
1864}; // namespace android