• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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