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