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