1 /*
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 #include <stdlib.h>
18 #include <stdint.h>
19 #include <sys/types.h>
20
21 #include <utils/Errors.h>
22 #include <utils/Log.h>
23 #include <binder/IPCThreadState.h>
24 #include <binder/IServiceManager.h>
25
26 #include <GLES/gl.h>
27 #include <GLES/glext.h>
28
29 #include <hardware/hardware.h>
30
31 #include "clz.h"
32 #include "LayerBase.h"
33 #include "SurfaceFlinger.h"
34 #include "DisplayHardware/DisplayHardware.h"
35
36 namespace android {
37
38 // ---------------------------------------------------------------------------
39
40 int32_t LayerBase::sSequence = 1;
41
LayerBase(SurfaceFlinger * flinger,DisplayID display)42 LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display)
43 : dpy(display), contentDirty(false),
44 sequence(uint32_t(android_atomic_inc(&sSequence))),
45 mFlinger(flinger), mFiltering(false),
46 mNeedsFiltering(false),
47 mOrientation(0),
48 mPlaneOrientation(0),
49 mTransactionFlags(0),
50 mPremultipliedAlpha(true), mName("unnamed"), mDebug(false)
51 {
52 const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware());
53 mFlags = hw.getFlags();
54 }
55
~LayerBase()56 LayerBase::~LayerBase()
57 {
58 }
59
setName(const String8 & name)60 void LayerBase::setName(const String8& name) {
61 mName = name;
62 }
63
getName() const64 String8 LayerBase::getName() const {
65 return mName;
66 }
67
graphicPlane(int dpy) const68 const GraphicPlane& LayerBase::graphicPlane(int dpy) const
69 {
70 return mFlinger->graphicPlane(dpy);
71 }
72
graphicPlane(int dpy)73 GraphicPlane& LayerBase::graphicPlane(int dpy)
74 {
75 return mFlinger->graphicPlane(dpy);
76 }
77
initStates(uint32_t w,uint32_t h,uint32_t flags)78 void LayerBase::initStates(uint32_t w, uint32_t h, uint32_t flags)
79 {
80 uint32_t layerFlags = 0;
81 if (flags & ISurfaceComposer::eHidden)
82 layerFlags = ISurfaceComposer::eLayerHidden;
83
84 if (flags & ISurfaceComposer::eNonPremultiplied)
85 mPremultipliedAlpha = false;
86
87 mCurrentState.active.w = w;
88 mCurrentState.active.h = h;
89 mCurrentState.active.crop.makeInvalid();
90 mCurrentState.z = 0;
91 mCurrentState.alpha = 0xFF;
92 mCurrentState.flags = layerFlags;
93 mCurrentState.sequence = 0;
94 mCurrentState.transform.set(0, 0);
95 mCurrentState.requested = mCurrentState.active;
96
97 // drawing state & current state are identical
98 mDrawingState = mCurrentState;
99 }
100
commitTransaction()101 void LayerBase::commitTransaction() {
102 mDrawingState = mCurrentState;
103 }
forceVisibilityTransaction()104 void LayerBase::forceVisibilityTransaction() {
105 // this can be called without SurfaceFlinger.mStateLock, but if we
106 // can atomically increment the sequence number, it doesn't matter.
107 android_atomic_inc(&mCurrentState.sequence);
108 requestTransaction();
109 }
requestTransaction()110 bool LayerBase::requestTransaction() {
111 int32_t old = setTransactionFlags(eTransactionNeeded);
112 return ((old & eTransactionNeeded) == 0);
113 }
getTransactionFlags(uint32_t flags)114 uint32_t LayerBase::getTransactionFlags(uint32_t flags) {
115 return android_atomic_and(~flags, &mTransactionFlags) & flags;
116 }
setTransactionFlags(uint32_t flags)117 uint32_t LayerBase::setTransactionFlags(uint32_t flags) {
118 return android_atomic_or(flags, &mTransactionFlags);
119 }
120
setPosition(float x,float y)121 bool LayerBase::setPosition(float x, float y) {
122 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
123 return false;
124 mCurrentState.sequence++;
125 mCurrentState.transform.set(x, y);
126 requestTransaction();
127 return true;
128 }
setLayer(uint32_t z)129 bool LayerBase::setLayer(uint32_t z) {
130 if (mCurrentState.z == z)
131 return false;
132 mCurrentState.sequence++;
133 mCurrentState.z = z;
134 requestTransaction();
135 return true;
136 }
setSize(uint32_t w,uint32_t h)137 bool LayerBase::setSize(uint32_t w, uint32_t h) {
138 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
139 return false;
140 mCurrentState.requested.w = w;
141 mCurrentState.requested.h = h;
142 requestTransaction();
143 return true;
144 }
setAlpha(uint8_t alpha)145 bool LayerBase::setAlpha(uint8_t alpha) {
146 if (mCurrentState.alpha == alpha)
147 return false;
148 mCurrentState.sequence++;
149 mCurrentState.alpha = alpha;
150 requestTransaction();
151 return true;
152 }
setMatrix(const layer_state_t::matrix22_t & matrix)153 bool LayerBase::setMatrix(const layer_state_t::matrix22_t& matrix) {
154 mCurrentState.sequence++;
155 mCurrentState.transform.set(
156 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
157 requestTransaction();
158 return true;
159 }
setTransparentRegionHint(const Region & transparent)160 bool LayerBase::setTransparentRegionHint(const Region& transparent) {
161 mCurrentState.sequence++;
162 mCurrentState.transparentRegion = transparent;
163 requestTransaction();
164 return true;
165 }
setFlags(uint8_t flags,uint8_t mask)166 bool LayerBase::setFlags(uint8_t flags, uint8_t mask) {
167 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
168 if (mCurrentState.flags == newFlags)
169 return false;
170 mCurrentState.sequence++;
171 mCurrentState.flags = newFlags;
172 requestTransaction();
173 return true;
174 }
setCrop(const Rect & crop)175 bool LayerBase::setCrop(const Rect& crop) {
176 if (mCurrentState.requested.crop == crop)
177 return false;
178 mCurrentState.sequence++;
179 mCurrentState.requested.crop = crop;
180 requestTransaction();
181 return true;
182 }
183
visibleBounds() const184 Rect LayerBase::visibleBounds() const
185 {
186 return mTransformedBounds;
187 }
188
setVisibleRegion(const Region & visibleRegion)189 void LayerBase::setVisibleRegion(const Region& visibleRegion) {
190 // always called from main thread
191 visibleRegionScreen = visibleRegion;
192 }
193
setCoveredRegion(const Region & coveredRegion)194 void LayerBase::setCoveredRegion(const Region& coveredRegion) {
195 // always called from main thread
196 coveredRegionScreen = coveredRegion;
197 }
198
doTransaction(uint32_t flags)199 uint32_t LayerBase::doTransaction(uint32_t flags)
200 {
201 const Layer::State& front(drawingState());
202 const Layer::State& temp(currentState());
203
204 // always set active to requested, unless we're asked not to
205 // this is used by Layer, which special cases resizes.
206 if (flags & eDontUpdateGeometryState) {
207 } else {
208 Layer::State& editTemp(currentState());
209 editTemp.active = temp.requested;
210 }
211
212 if (front.active != temp.active) {
213 // invalidate and recompute the visible regions if needed
214 flags |= Layer::eVisibleRegion;
215 }
216
217 if (temp.sequence != front.sequence) {
218 // invalidate and recompute the visible regions if needed
219 flags |= eVisibleRegion;
220 this->contentDirty = true;
221
222 // we may use linear filtering, if the matrix scales us
223 const uint8_t type = temp.transform.getType();
224 mNeedsFiltering = (!temp.transform.preserveRects() ||
225 (type >= Transform::SCALE));
226 }
227
228 // Commit the transaction
229 commitTransaction();
230 return flags;
231 }
232
validateVisibility(const Transform & planeTransform)233 void LayerBase::validateVisibility(const Transform& planeTransform)
234 {
235 const Layer::State& s(drawingState());
236 const Transform tr(planeTransform * s.transform);
237 const bool transformed = tr.transformed();
238 const DisplayHardware& hw(graphicPlane(0).displayHardware());
239 const uint32_t hw_h = hw.getHeight();
240 const Rect& crop(s.active.crop);
241
242 Rect win(s.active.w, s.active.h);
243 if (!crop.isEmpty()) {
244 win.intersect(crop, &win);
245 }
246
247 mNumVertices = 4;
248 tr.transform(mVertices[0], win.left, win.top);
249 tr.transform(mVertices[1], win.left, win.bottom);
250 tr.transform(mVertices[2], win.right, win.bottom);
251 tr.transform(mVertices[3], win.right, win.top);
252 for (size_t i=0 ; i<4 ; i++)
253 mVertices[i][1] = hw_h - mVertices[i][1];
254
255 if (CC_UNLIKELY(transformed)) {
256 // NOTE: here we could also punt if we have too many rectangles
257 // in the transparent region
258 if (tr.preserveRects()) {
259 // transform the transparent region
260 transparentRegionScreen = tr.transform(s.transparentRegion);
261 } else {
262 // transformation too complex, can't do the transparent region
263 // optimization.
264 transparentRegionScreen.clear();
265 }
266 } else {
267 transparentRegionScreen = s.transparentRegion;
268 }
269
270 // cache a few things...
271 mOrientation = tr.getOrientation();
272 mPlaneOrientation = planeTransform.getOrientation();
273 mTransform = tr;
274 mTransformedBounds = tr.transform(win);
275 }
276
lockPageFlip(bool & recomputeVisibleRegions)277 void LayerBase::lockPageFlip(bool& recomputeVisibleRegions) {
278 }
279
unlockPageFlip(const Transform & planeTransform,Region & outDirtyRegion)280 void LayerBase::unlockPageFlip(
281 const Transform& planeTransform, Region& outDirtyRegion) {
282 }
283
setGeometry(hwc_layer_t * hwcl)284 void LayerBase::setGeometry(hwc_layer_t* hwcl)
285 {
286 hwcl->compositionType = HWC_FRAMEBUFFER;
287 hwcl->hints = 0;
288 hwcl->flags = HWC_SKIP_LAYER;
289 hwcl->transform = 0;
290 hwcl->blending = HWC_BLENDING_NONE;
291
292 // this gives us only the "orientation" component of the transform
293 const State& s(drawingState());
294 const uint32_t finalTransform = s.transform.getOrientation();
295 // we can only handle simple transformation
296 if (finalTransform & Transform::ROT_INVALID) {
297 hwcl->flags = HWC_SKIP_LAYER;
298 } else {
299 hwcl->transform = finalTransform;
300 }
301
302 if (!isOpaque()) {
303 hwcl->blending = mPremultipliedAlpha ?
304 HWC_BLENDING_PREMULT : HWC_BLENDING_COVERAGE;
305 }
306
307 // scaling is already applied in mTransformedBounds
308 hwcl->displayFrame.left = mTransformedBounds.left;
309 hwcl->displayFrame.top = mTransformedBounds.top;
310 hwcl->displayFrame.right = mTransformedBounds.right;
311 hwcl->displayFrame.bottom = mTransformedBounds.bottom;
312 hwcl->visibleRegionScreen.rects =
313 reinterpret_cast<hwc_rect_t const *>(
314 visibleRegionScreen.getArray(
315 &hwcl->visibleRegionScreen.numRects));
316
317 hwcl->sourceCrop.left = 0;
318 hwcl->sourceCrop.top = 0;
319 hwcl->sourceCrop.right = mTransformedBounds.width();
320 hwcl->sourceCrop.bottom = mTransformedBounds.height();
321 }
322
setPerFrameData(hwc_layer_t * hwcl)323 void LayerBase::setPerFrameData(hwc_layer_t* hwcl) {
324 hwcl->compositionType = HWC_FRAMEBUFFER;
325 hwcl->handle = NULL;
326 }
327
setFiltering(bool filtering)328 void LayerBase::setFiltering(bool filtering)
329 {
330 mFiltering = filtering;
331 }
332
getFiltering() const333 bool LayerBase::getFiltering() const
334 {
335 return mFiltering;
336 }
337
draw(const Region & clip) const338 void LayerBase::draw(const Region& clip) const
339 {
340 onDraw(clip);
341 }
342
drawForSreenShot()343 void LayerBase::drawForSreenShot()
344 {
345 const DisplayHardware& hw(graphicPlane(0).displayHardware());
346 setFiltering(true);
347 onDraw( Region(hw.bounds()) );
348 setFiltering(false);
349 }
350
clearWithOpenGL(const Region & clip,GLclampf red,GLclampf green,GLclampf blue,GLclampf alpha) const351 void LayerBase::clearWithOpenGL(const Region& clip, GLclampf red,
352 GLclampf green, GLclampf blue,
353 GLclampf alpha) const
354 {
355 const DisplayHardware& hw(graphicPlane(0).displayHardware());
356 const uint32_t fbHeight = hw.getHeight();
357 glColor4f(red,green,blue,alpha);
358
359 glDisable(GL_TEXTURE_EXTERNAL_OES);
360 glDisable(GL_TEXTURE_2D);
361 glDisable(GL_BLEND);
362
363 glVertexPointer(2, GL_FLOAT, 0, mVertices);
364 glDrawArrays(GL_TRIANGLE_FAN, 0, mNumVertices);
365 }
366
clearWithOpenGL(const Region & clip) const367 void LayerBase::clearWithOpenGL(const Region& clip) const
368 {
369 clearWithOpenGL(clip,0,0,0,0);
370 }
371
drawWithOpenGL(const Region & clip) const372 void LayerBase::drawWithOpenGL(const Region& clip) const
373 {
374 const DisplayHardware& hw(graphicPlane(0).displayHardware());
375 const uint32_t fbHeight = hw.getHeight();
376 const State& s(drawingState());
377
378 GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
379 if (CC_UNLIKELY(s.alpha < 0xFF)) {
380 const GLfloat alpha = s.alpha * (1.0f/255.0f);
381 if (mPremultipliedAlpha) {
382 glColor4f(alpha, alpha, alpha, alpha);
383 } else {
384 glColor4f(1, 1, 1, alpha);
385 }
386 glEnable(GL_BLEND);
387 glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
388 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
389 } else {
390 glColor4f(1, 1, 1, 1);
391 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
392 if (!isOpaque()) {
393 glEnable(GL_BLEND);
394 glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
395 } else {
396 glDisable(GL_BLEND);
397 }
398 }
399
400 struct TexCoords {
401 GLfloat u;
402 GLfloat v;
403 };
404
405 Rect crop(s.active.w, s.active.h);
406 if (!s.active.crop.isEmpty()) {
407 crop = s.active.crop;
408 }
409 GLfloat left = GLfloat(crop.left) / GLfloat(s.active.w);
410 GLfloat top = GLfloat(crop.top) / GLfloat(s.active.h);
411 GLfloat right = GLfloat(crop.right) / GLfloat(s.active.w);
412 GLfloat bottom = GLfloat(crop.bottom) / GLfloat(s.active.h);
413
414 TexCoords texCoords[4];
415 texCoords[0].u = left;
416 texCoords[0].v = top;
417 texCoords[1].u = left;
418 texCoords[1].v = bottom;
419 texCoords[2].u = right;
420 texCoords[2].v = bottom;
421 texCoords[3].u = right;
422 texCoords[3].v = top;
423 for (int i = 0; i < 4; i++) {
424 texCoords[i].v = 1.0f - texCoords[i].v;
425 }
426
427 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
428 glVertexPointer(2, GL_FLOAT, 0, mVertices);
429 glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
430 glDrawArrays(GL_TRIANGLE_FAN, 0, mNumVertices);
431
432 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
433 glDisable(GL_BLEND);
434 }
435
dump(String8 & result,char * buffer,size_t SIZE) const436 void LayerBase::dump(String8& result, char* buffer, size_t SIZE) const
437 {
438 const Layer::State& s(drawingState());
439
440 snprintf(buffer, SIZE,
441 "+ %s %p (%s)\n",
442 getTypeId(), this, getName().string());
443 result.append(buffer);
444
445 s.transparentRegion.dump(result, "transparentRegion");
446 transparentRegionScreen.dump(result, "transparentRegionScreen");
447 visibleRegionScreen.dump(result, "visibleRegionScreen");
448
449 snprintf(buffer, SIZE,
450 " "
451 "z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
452 "isOpaque=%1d, needsDithering=%1d, invalidate=%1d, "
453 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n",
454 s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
455 s.active.crop.left, s.active.crop.top,
456 s.active.crop.right, s.active.crop.bottom,
457 isOpaque(), needsDithering(), contentDirty,
458 s.alpha, s.flags,
459 s.transform[0][0], s.transform[0][1],
460 s.transform[1][0], s.transform[1][1]);
461 result.append(buffer);
462 }
463
shortDump(String8 & result,char * scratch,size_t size) const464 void LayerBase::shortDump(String8& result, char* scratch, size_t size) const {
465 LayerBase::dump(result, scratch, size);
466 }
467
dumpStats(String8 & result,char * scratch,size_t SIZE) const468 void LayerBase::dumpStats(String8& result, char* scratch, size_t SIZE) const {
469 }
470
clearStats()471 void LayerBase::clearStats() {
472 }
473
474 // ---------------------------------------------------------------------------
475
476 int32_t LayerBaseClient::sIdentity = 1;
477
LayerBaseClient(SurfaceFlinger * flinger,DisplayID display,const sp<Client> & client)478 LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
479 const sp<Client>& client)
480 : LayerBase(flinger, display),
481 mHasSurface(false),
482 mClientRef(client),
483 mIdentity(uint32_t(android_atomic_inc(&sIdentity)))
484 {
485 }
486
~LayerBaseClient()487 LayerBaseClient::~LayerBaseClient()
488 {
489 sp<Client> c(mClientRef.promote());
490 if (c != 0) {
491 c->detachLayer(this);
492 }
493 }
494
createSurface()495 sp<ISurface> LayerBaseClient::createSurface()
496 {
497 class BSurface : public BnSurface, public LayerCleaner {
498 virtual sp<ISurfaceTexture> getSurfaceTexture() const { return 0; }
499 public:
500 BSurface(const sp<SurfaceFlinger>& flinger,
501 const sp<LayerBaseClient>& layer)
502 : LayerCleaner(flinger, layer) { }
503 };
504 sp<ISurface> sur(new BSurface(mFlinger, this));
505 return sur;
506 }
507
getSurface()508 sp<ISurface> LayerBaseClient::getSurface()
509 {
510 sp<ISurface> s;
511 Mutex::Autolock _l(mLock);
512
513 LOG_ALWAYS_FATAL_IF(mHasSurface,
514 "LayerBaseClient::getSurface() has already been called");
515
516 mHasSurface = true;
517 s = createSurface();
518 mClientSurfaceBinder = s->asBinder();
519 return s;
520 }
521
getSurfaceBinder() const522 wp<IBinder> LayerBaseClient::getSurfaceBinder() const {
523 return mClientSurfaceBinder;
524 }
525
getSurfaceTextureBinder() const526 wp<IBinder> LayerBaseClient::getSurfaceTextureBinder() const {
527 return 0;
528 }
529
dump(String8 & result,char * buffer,size_t SIZE) const530 void LayerBaseClient::dump(String8& result, char* buffer, size_t SIZE) const
531 {
532 LayerBase::dump(result, buffer, SIZE);
533
534 sp<Client> client(mClientRef.promote());
535 snprintf(buffer, SIZE,
536 " client=%p, identity=%u\n",
537 client.get(), getIdentity());
538
539 result.append(buffer);
540 }
541
542
shortDump(String8 & result,char * scratch,size_t size) const543 void LayerBaseClient::shortDump(String8& result, char* scratch, size_t size) const
544 {
545 LayerBaseClient::dump(result, scratch, size);
546 }
547
548 // ---------------------------------------------------------------------------
549
LayerCleaner(const sp<SurfaceFlinger> & flinger,const sp<LayerBaseClient> & layer)550 LayerBaseClient::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
551 const sp<LayerBaseClient>& layer)
552 : mFlinger(flinger), mLayer(layer) {
553 }
554
~LayerCleaner()555 LayerBaseClient::LayerCleaner::~LayerCleaner() {
556 // destroy client resources
557 mFlinger->destroySurface(mLayer);
558 }
559
560 // ---------------------------------------------------------------------------
561
562 }; // namespace android
563