OSDN Git Service

SurfaceFlinger: add support for secure displays
[android-x86/frameworks-native.git] / services / surfaceflinger / Layer.cpp
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 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
18
19 #include <stdlib.h>
20 #include <stdint.h>
21 #include <sys/types.h>
22 #include <math.h>
23
24 #include <cutils/compiler.h>
25 #include <cutils/native_handle.h>
26 #include <cutils/properties.h>
27
28 #include <utils/Errors.h>
29 #include <utils/Log.h>
30 #include <utils/StopWatch.h>
31 #include <utils/Trace.h>
32
33 #include <ui/GraphicBuffer.h>
34 #include <ui/PixelFormat.h>
35
36 #include <gui/Surface.h>
37
38 #include "clz.h"
39 #include "DisplayDevice.h"
40 #include "GLExtensions.h"
41 #include "Layer.h"
42 #include "SurfaceFlinger.h"
43 #include "SurfaceTextureLayer.h"
44
45 #include "DisplayHardware/HWComposer.h"
46
47 #define DEBUG_RESIZE    0
48
49 namespace android {
50
51 // ---------------------------------------------------------------------------
52
53 Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client)
54     :   LayerBaseClient(flinger, client),
55         mTextureName(-1U),
56         mQueuedFrames(0),
57         mCurrentTransform(0),
58         mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
59         mCurrentOpacity(true),
60         mRefreshPending(false),
61         mFrameLatencyNeeded(false),
62         mFrameLatencyOffset(0),
63         mFormat(PIXEL_FORMAT_NONE),
64         mGLExtensions(GLExtensions::getInstance()),
65         mOpaqueLayer(true),
66         mSecure(false),
67         mProtectedByApp(false)
68 {
69     mCurrentCrop.makeInvalid();
70     glGenTextures(1, &mTextureName);
71 }
72
73 void Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw,
74         HWComposer::HWCLayerInterface* layer) {
75     LayerBaseClient::onLayerDisplayed(hw, layer);
76     if (layer) {
77         mSurfaceTexture->setReleaseFence(layer->getAndResetReleaseFenceFd());
78     }
79 }
80
81 void Layer::onFirstRef()
82 {
83     LayerBaseClient::onFirstRef();
84
85     struct FrameQueuedListener : public SurfaceTexture::FrameAvailableListener {
86         FrameQueuedListener(Layer* layer) : mLayer(layer) { }
87     private:
88         wp<Layer> mLayer;
89         virtual void onFrameAvailable() {
90             sp<Layer> that(mLayer.promote());
91             if (that != 0) {
92                 that->onFrameQueued();
93             }
94         }
95     };
96
97     // Creates a custom BufferQueue for SurfaceTexture to use
98     sp<BufferQueue> bq = new SurfaceTextureLayer();
99     mSurfaceTexture = new SurfaceTexture(mTextureName, true,
100             GL_TEXTURE_EXTERNAL_OES, false, bq);
101
102     mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0));
103     mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this));
104     mSurfaceTexture->setSynchronousMode(true);
105
106 #ifdef TARGET_DISABLE_TRIPLE_BUFFERING
107 #warning "disabling triple buffering"
108     mSurfaceTexture->setDefaultMaxBufferCount(2);
109 #else
110     mSurfaceTexture->setDefaultMaxBufferCount(3);
111 #endif
112
113     updateTransformHint();
114 }
115
116 Layer::~Layer()
117 {
118     mFlinger->deleteTextureAsync(mTextureName);
119 }
120
121 void Layer::onFrameQueued() {
122     android_atomic_inc(&mQueuedFrames);
123     mFlinger->signalLayerUpdate();
124 }
125
126 // called with SurfaceFlinger::mStateLock as soon as the layer is entered
127 // in the purgatory list
128 void Layer::onRemoved()
129 {
130     mSurfaceTexture->abandon();
131 }
132
133 void Layer::setName(const String8& name) {
134     LayerBase::setName(name);
135     mSurfaceTexture->setName(name);
136 }
137
138 sp<ISurface> Layer::createSurface()
139 {
140     class BSurface : public BnSurface, public LayerCleaner {
141         wp<const Layer> mOwner;
142         virtual sp<ISurfaceTexture> getSurfaceTexture() const {
143             sp<ISurfaceTexture> res;
144             sp<const Layer> that( mOwner.promote() );
145             if (that != NULL) {
146                 res = that->mSurfaceTexture->getBufferQueue();
147             }
148             return res;
149         }
150     public:
151         BSurface(const sp<SurfaceFlinger>& flinger,
152                 const sp<Layer>& layer)
153             : LayerCleaner(flinger, layer), mOwner(layer) { }
154     };
155     sp<ISurface> sur(new BSurface(mFlinger, this));
156     return sur;
157 }
158
159 wp<IBinder> Layer::getSurfaceTextureBinder() const
160 {
161     return mSurfaceTexture->getBufferQueue()->asBinder();
162 }
163
164 status_t Layer::setBuffers( uint32_t w, uint32_t h,
165                             PixelFormat format, uint32_t flags)
166 {
167     // this surfaces pixel format
168     PixelFormatInfo info;
169     status_t err = getPixelFormatInfo(format, &info);
170     if (err) {
171         ALOGE("unsupported pixelformat %d", format);
172         return err;
173     }
174
175     uint32_t const maxSurfaceDims = min(
176             mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
177
178     // never allow a surface larger than what our underlying GL implementation
179     // can handle.
180     if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
181         ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
182         return BAD_VALUE;
183     }
184
185     mFormat = format;
186
187     mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
188     mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
189     mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque);
190     mCurrentOpacity = getOpacityForFormat(format);
191
192     mSurfaceTexture->setDefaultBufferSize(w, h);
193     mSurfaceTexture->setDefaultBufferFormat(format);
194     mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0));
195
196     return NO_ERROR;
197 }
198
199 Rect Layer::computeBufferCrop() const {
200     // Start with the SurfaceTexture's buffer crop...
201     Rect crop;
202     if (!mCurrentCrop.isEmpty()) {
203         crop = mCurrentCrop;
204     } else  if (mActiveBuffer != NULL){
205         crop = Rect(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
206     } else {
207         crop.makeInvalid();
208         return crop;
209     }
210
211     // ... then reduce that in the same proportions as the window crop reduces
212     // the window size.
213     const State& s(drawingState());
214     if (!s.active.crop.isEmpty()) {
215         // Transform the window crop to match the buffer coordinate system,
216         // which means using the inverse of the current transform set on the
217         // SurfaceTexture.
218         uint32_t invTransform = mCurrentTransform;
219         int winWidth = s.active.w;
220         int winHeight = s.active.h;
221         if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
222             invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
223                     NATIVE_WINDOW_TRANSFORM_FLIP_H;
224             winWidth = s.active.h;
225             winHeight = s.active.w;
226         }
227         Rect winCrop = s.active.crop.transform(invTransform,
228                 s.active.w, s.active.h);
229
230         float xScale = float(crop.width()) / float(winWidth);
231         float yScale = float(crop.height()) / float(winHeight);
232         crop.left += int(ceilf(float(winCrop.left) * xScale));
233         crop.top += int(ceilf(float(winCrop.top) * yScale));
234         crop.right -= int(ceilf(float(winWidth - winCrop.right) * xScale));
235         crop.bottom -= int(ceilf(float(winHeight - winCrop.bottom) * yScale));
236     }
237
238     return crop;
239 }
240
241 void Layer::setGeometry(
242     const sp<const DisplayDevice>& hw,
243         HWComposer::HWCLayerInterface& layer)
244 {
245     LayerBaseClient::setGeometry(hw, layer);
246
247     // enable this layer
248     layer.setSkip(false);
249
250     // we can't do alpha-fade with the hwc HAL
251     const State& s(drawingState());
252     if (s.alpha < 0xFF) {
253         layer.setSkip(true);
254     }
255
256     if (isSecure() && !hw->isSecure()) {
257         layer.setSkip(true);
258     }
259
260     /*
261      * Transformations are applied in this order:
262      * 1) buffer orientation/flip/mirror
263      * 2) state transformation (window manager)
264      * 3) layer orientation (screen orientation)
265      * (NOTE: the matrices are multiplied in reverse order)
266      */
267
268     const Transform bufferOrientation(mCurrentTransform);
269     const Transform tr(hw->getTransform() * s.transform * bufferOrientation);
270
271     // this gives us only the "orientation" component of the transform
272     const uint32_t finalTransform = tr.getOrientation();
273
274     // we can only handle simple transformation
275     if (finalTransform & Transform::ROT_INVALID) {
276         layer.setSkip(true);
277     } else {
278         layer.setTransform(finalTransform);
279     }
280     layer.setCrop(computeBufferCrop());
281 }
282
283 void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
284         HWComposer::HWCLayerInterface& layer) {
285     LayerBaseClient::setPerFrameData(hw, layer);
286     // NOTE: buffer can be NULL if the client never drew into this
287     // layer yet, or if we ran out of memory
288     layer.setBuffer(mActiveBuffer);
289 }
290
291 void Layer::setAcquireFence(const sp<const DisplayDevice>& hw,
292         HWComposer::HWCLayerInterface& layer) {
293     int fenceFd = -1;
294
295     // TODO: there is a possible optimization here: we only need to set the
296     // acquire fence the first time a new buffer is acquired on EACH display.
297
298     if (layer.getCompositionType() == HWC_OVERLAY) {
299         sp<Fence> fence = mSurfaceTexture->getCurrentFence();
300         if (fence.get()) {
301             fenceFd = fence->dup();
302             if (fenceFd == -1) {
303                 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
304             }
305         }
306     }
307     layer.setAcquireFenceFd(fenceFd);
308 }
309
310 void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
311 {
312     ATRACE_CALL();
313
314     if (CC_UNLIKELY(mActiveBuffer == 0)) {
315         // the texture has not been created yet, this Layer has
316         // in fact never been drawn into. This happens frequently with
317         // SurfaceView because the WindowManager can't know when the client
318         // has drawn the first time.
319
320         // If there is nothing under us, we paint the screen in black, otherwise
321         // we just skip this update.
322
323         // figure out if there is something below us
324         Region under;
325         const SurfaceFlinger::LayerVector& drawingLayers(
326                 mFlinger->mDrawingState.layersSortedByZ);
327         const size_t count = drawingLayers.size();
328         for (size_t i=0 ; i<count ; ++i) {
329             const sp<LayerBase>& layer(drawingLayers[i]);
330             if (layer.get() == static_cast<LayerBase const*>(this))
331                 break;
332             under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
333         }
334         // if not everything below us is covered, we plug the holes!
335         Region holes(clip.subtract(under));
336         if (!holes.isEmpty()) {
337             clearWithOpenGL(hw, holes, 0, 0, 0, 1);
338         }
339         return;
340     }
341
342     status_t err = mSurfaceTexture->doGLFenceWait();
343     if (err != OK) {
344         ALOGE("onDraw: failed waiting for fence: %d", err);
345         // Go ahead and draw the buffer anyway; no matter what we do the screen
346         // is probably going to have something visibly wrong.
347     }
348
349     bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
350
351     if (!blackOutLayer) {
352         // TODO: we could be more subtle with isFixedSize()
353         const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
354
355         // Query the texture matrix given our current filtering mode.
356         float textureMatrix[16];
357         mSurfaceTexture->setFilteringEnabled(useFiltering);
358         mSurfaceTexture->getTransformMatrix(textureMatrix);
359
360         // Set things up for texturing.
361         glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName);
362         GLenum filter = GL_NEAREST;
363         if (useFiltering) {
364             filter = GL_LINEAR;
365         }
366         glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter);
367         glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter);
368         glMatrixMode(GL_TEXTURE);
369         glLoadMatrixf(textureMatrix);
370         glMatrixMode(GL_MODELVIEW);
371         glDisable(GL_TEXTURE_2D);
372         glEnable(GL_TEXTURE_EXTERNAL_OES);
373     } else {
374         glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName());
375         glMatrixMode(GL_TEXTURE);
376         glLoadIdentity();
377         glMatrixMode(GL_MODELVIEW);
378         glDisable(GL_TEXTURE_EXTERNAL_OES);
379         glEnable(GL_TEXTURE_2D);
380     }
381
382     drawWithOpenGL(hw, clip);
383
384     glDisable(GL_TEXTURE_EXTERNAL_OES);
385     glDisable(GL_TEXTURE_2D);
386 }
387
388 // As documented in libhardware header, formats in the range
389 // 0x100 - 0x1FF are specific to the HAL implementation, and
390 // are known to have no alpha channel
391 // TODO: move definition for device-specific range into
392 // hardware.h, instead of using hard-coded values here.
393 #define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
394
395 bool Layer::getOpacityForFormat(uint32_t format)
396 {
397     if (HARDWARE_IS_DEVICE_FORMAT(format)) {
398         return true;
399     }
400     PixelFormatInfo info;
401     status_t err = getPixelFormatInfo(PixelFormat(format), &info);
402     // in case of error (unknown format), we assume no blending
403     return (err || info.h_alpha <= info.l_alpha);
404 }
405
406
407 bool Layer::isOpaque() const
408 {
409     // if we don't have a buffer yet, we're translucent regardless of the
410     // layer's opaque flag.
411     if (mActiveBuffer == 0) {
412         return false;
413     }
414
415     // if the layer has the opaque flag, then we're always opaque,
416     // otherwise we use the current buffer's format.
417     return mOpaqueLayer || mCurrentOpacity;
418 }
419
420 bool Layer::isProtected() const
421 {
422     const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
423     return (activeBuffer != 0) &&
424             (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
425 }
426
427 uint32_t Layer::doTransaction(uint32_t flags)
428 {
429     ATRACE_CALL();
430
431     const Layer::State& front(drawingState());
432     const Layer::State& temp(currentState());
433
434     const bool sizeChanged = (temp.requested.w != front.requested.w) ||
435                              (temp.requested.h != front.requested.h);
436
437     if (sizeChanged) {
438         // the size changed, we need to ask our client to request a new buffer
439         ALOGD_IF(DEBUG_RESIZE,
440                 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
441                 "  current={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
442                 "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
443                 "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
444                 "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
445                 this, (const char*) getName(), mCurrentTransform, mCurrentScalingMode,
446                 temp.active.w, temp.active.h,
447                 temp.active.crop.left,
448                 temp.active.crop.top,
449                 temp.active.crop.right,
450                 temp.active.crop.bottom,
451                 temp.active.crop.getWidth(),
452                 temp.active.crop.getHeight(),
453                 temp.requested.w, temp.requested.h,
454                 temp.requested.crop.left,
455                 temp.requested.crop.top,
456                 temp.requested.crop.right,
457                 temp.requested.crop.bottom,
458                 temp.requested.crop.getWidth(),
459                 temp.requested.crop.getHeight(),
460                 front.active.w, front.active.h,
461                 front.active.crop.left,
462                 front.active.crop.top,
463                 front.active.crop.right,
464                 front.active.crop.bottom,
465                 front.active.crop.getWidth(),
466                 front.active.crop.getHeight(),
467                 front.requested.w, front.requested.h,
468                 front.requested.crop.left,
469                 front.requested.crop.top,
470                 front.requested.crop.right,
471                 front.requested.crop.bottom,
472                 front.requested.crop.getWidth(),
473                 front.requested.crop.getHeight());
474
475         // record the new size, form this point on, when the client request
476         // a buffer, it'll get the new size.
477         mSurfaceTexture->setDefaultBufferSize(
478                 temp.requested.w, temp.requested.h);
479     }
480
481     if (!isFixedSize()) {
482
483         const bool resizePending = (temp.requested.w != temp.active.w) ||
484                                    (temp.requested.h != temp.active.h);
485
486         if (resizePending) {
487             // don't let LayerBase::doTransaction update the drawing state
488             // if we have a pending resize, unless we are in fixed-size mode.
489             // the drawing state will be updated only once we receive a buffer
490             // with the correct size.
491             //
492             // in particular, we want to make sure the clip (which is part
493             // of the geometry state) is latched together with the size but is
494             // latched immediately when no resizing is involved.
495
496             flags |= eDontUpdateGeometryState;
497         }
498     }
499
500     return LayerBase::doTransaction(flags);
501 }
502
503 bool Layer::isFixedSize() const {
504     return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
505 }
506
507 bool Layer::isCropped() const {
508     return !mCurrentCrop.isEmpty();
509 }
510
511 // ----------------------------------------------------------------------------
512 // pageflip handling...
513 // ----------------------------------------------------------------------------
514
515 bool Layer::onPreComposition() {
516     mRefreshPending = false;
517     return mQueuedFrames > 0;
518 }
519
520 void Layer::onPostComposition() {
521     if (mFrameLatencyNeeded) {
522         const HWComposer& hwc = mFlinger->getHwComposer();
523         const size_t offset = mFrameLatencyOffset;
524         mFrameStats[offset].timestamp = mSurfaceTexture->getTimestamp();
525         mFrameStats[offset].set = systemTime();
526         mFrameStats[offset].vsync = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
527         mFrameLatencyOffset = (mFrameLatencyOffset + 1) % 128;
528         mFrameLatencyNeeded = false;
529     }
530 }
531
532 bool Layer::isVisible() const {
533     return LayerBaseClient::isVisible() && (mActiveBuffer != NULL);
534 }
535
536 Region Layer::latchBuffer(bool& recomputeVisibleRegions)
537 {
538     ATRACE_CALL();
539
540     Region outDirtyRegion;
541     if (mQueuedFrames > 0) {
542
543         // if we've already called updateTexImage() without going through
544         // a composition step, we have to skip this layer at this point
545         // because we cannot call updateTeximage() without a corresponding
546         // compositionComplete() call.
547         // we'll trigger an update in onPreComposition().
548         if (mRefreshPending) {
549             return outDirtyRegion;
550         }
551
552         // Capture the old state of the layer for comparisons later
553         const bool oldOpacity = isOpaque();
554         sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
555
556         // signal another event if we have more frames pending
557         if (android_atomic_dec(&mQueuedFrames) > 1) {
558             mFlinger->signalLayerUpdate();
559         }
560
561         struct Reject : public SurfaceTexture::BufferRejecter {
562             Layer::State& front;
563             Layer::State& current;
564             bool& recomputeVisibleRegions;
565             Reject(Layer::State& front, Layer::State& current,
566                     bool& recomputeVisibleRegions)
567                 : front(front), current(current),
568                   recomputeVisibleRegions(recomputeVisibleRegions) {
569             }
570
571             virtual bool reject(const sp<GraphicBuffer>& buf,
572                     const BufferQueue::BufferItem& item) {
573                 if (buf == NULL) {
574                     return false;
575                 }
576
577                 uint32_t bufWidth  = buf->getWidth();
578                 uint32_t bufHeight = buf->getHeight();
579
580                 // check that we received a buffer of the right size
581                 // (Take the buffer's orientation into account)
582                 if (item.mTransform & Transform::ROT_90) {
583                     swap(bufWidth, bufHeight);
584                 }
585
586
587                 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
588                 if (front.active != front.requested) {
589
590                     if (isFixedSize ||
591                             (bufWidth == front.requested.w &&
592                              bufHeight == front.requested.h))
593                     {
594                         // Here we pretend the transaction happened by updating the
595                         // current and drawing states. Drawing state is only accessed
596                         // in this thread, no need to have it locked
597                         front.active = front.requested;
598
599                         // We also need to update the current state so that
600                         // we don't end-up overwriting the drawing state with
601                         // this stale current state during the next transaction
602                         //
603                         // NOTE: We don't need to hold the transaction lock here
604                         // because State::active is only accessed from this thread.
605                         current.active = front.active;
606
607                         // recompute visible region
608                         recomputeVisibleRegions = true;
609                     }
610
611                     ALOGD_IF(DEBUG_RESIZE,
612                             "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
613                             "  drawing={ active   ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
614                             "            requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
615                             bufWidth, bufHeight, item.mTransform, item.mScalingMode,
616                             front.active.w, front.active.h,
617                             front.active.crop.left,
618                             front.active.crop.top,
619                             front.active.crop.right,
620                             front.active.crop.bottom,
621                             front.active.crop.getWidth(),
622                             front.active.crop.getHeight(),
623                             front.requested.w, front.requested.h,
624                             front.requested.crop.left,
625                             front.requested.crop.top,
626                             front.requested.crop.right,
627                             front.requested.crop.bottom,
628                             front.requested.crop.getWidth(),
629                             front.requested.crop.getHeight());
630                 }
631
632                 if (!isFixedSize) {
633                     if (front.active.w != bufWidth ||
634                         front.active.h != bufHeight) {
635                         // reject this buffer
636                         return true;
637                     }
638                 }
639                 return false;
640             }
641         };
642
643
644         Reject r(mDrawingState, currentState(), recomputeVisibleRegions);
645
646         if (mSurfaceTexture->updateTexImage(&r, true) < NO_ERROR) {
647             // something happened!
648             recomputeVisibleRegions = true;
649             return outDirtyRegion;
650         }
651
652         // update the active buffer
653         mActiveBuffer = mSurfaceTexture->getCurrentBuffer();
654         if (mActiveBuffer == NULL) {
655             // this can only happen if the very first buffer was rejected.
656             return outDirtyRegion;
657         }
658
659         mRefreshPending = true;
660         mFrameLatencyNeeded = true;
661         if (oldActiveBuffer == NULL) {
662              // the first time we receive a buffer, we need to trigger a
663              // geometry invalidation.
664             recomputeVisibleRegions = true;
665          }
666
667         Rect crop(mSurfaceTexture->getCurrentCrop());
668         const uint32_t transform(mSurfaceTexture->getCurrentTransform());
669         const uint32_t scalingMode(mSurfaceTexture->getCurrentScalingMode());
670         if ((crop != mCurrentCrop) ||
671             (transform != mCurrentTransform) ||
672             (scalingMode != mCurrentScalingMode))
673         {
674             mCurrentCrop = crop;
675             mCurrentTransform = transform;
676             mCurrentScalingMode = scalingMode;
677             recomputeVisibleRegions = true;
678         }
679
680         if (oldActiveBuffer != NULL) {
681             uint32_t bufWidth  = mActiveBuffer->getWidth();
682             uint32_t bufHeight = mActiveBuffer->getHeight();
683             if (bufWidth != uint32_t(oldActiveBuffer->width) ||
684                 bufHeight != uint32_t(oldActiveBuffer->height)) {
685                 recomputeVisibleRegions = true;
686             }
687         }
688
689         mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
690         if (oldOpacity != isOpaque()) {
691             recomputeVisibleRegions = true;
692         }
693
694         glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
695         glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
696
697         // FIXME: postedRegion should be dirty & bounds
698         const Layer::State& front(drawingState());
699         Region dirtyRegion(Rect(front.active.w, front.active.h));
700
701         // transform the dirty region to window-manager space
702         outDirtyRegion = (front.transform.transform(dirtyRegion));
703     }
704     return outDirtyRegion;
705 }
706
707 void Layer::dump(String8& result, char* buffer, size_t SIZE) const
708 {
709     LayerBaseClient::dump(result, buffer, SIZE);
710
711     sp<const GraphicBuffer> buf0(mActiveBuffer);
712     uint32_t w0=0, h0=0, s0=0, f0=0;
713     if (buf0 != 0) {
714         w0 = buf0->getWidth();
715         h0 = buf0->getHeight();
716         s0 = buf0->getStride();
717         f0 = buf0->format;
718     }
719     snprintf(buffer, SIZE,
720             "      "
721             "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
722             " queued-frames=%d, mRefreshPending=%d\n",
723             mFormat, w0, h0, s0,f0,
724             mQueuedFrames, mRefreshPending);
725
726     result.append(buffer);
727
728     if (mSurfaceTexture != 0) {
729         mSurfaceTexture->dump(result, "            ", buffer, SIZE);
730     }
731 }
732
733 void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const
734 {
735     LayerBaseClient::dumpStats(result, buffer, SIZE);
736     const size_t o = mFrameLatencyOffset;
737     const nsecs_t period =
738             mFlinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
739     result.appendFormat("%lld\n", period);
740     for (size_t i=0 ; i<128 ; i++) {
741         const size_t index = (o+i) % 128;
742         const nsecs_t time_app   = mFrameStats[index].timestamp;
743         const nsecs_t time_set   = mFrameStats[index].set;
744         const nsecs_t time_vsync = mFrameStats[index].vsync;
745         result.appendFormat("%lld\t%lld\t%lld\n",
746                 time_app,
747                 time_vsync,
748                 time_set);
749     }
750     result.append("\n");
751 }
752
753 void Layer::clearStats()
754 {
755     LayerBaseClient::clearStats();
756     memset(mFrameStats, 0, sizeof(mFrameStats));
757 }
758
759 uint32_t Layer::getEffectiveUsage(uint32_t usage) const
760 {
761     // TODO: should we do something special if mSecure is set?
762     if (mProtectedByApp) {
763         // need a hardware-protected path to external video sink
764         usage |= GraphicBuffer::USAGE_PROTECTED;
765     }
766     usage |= GraphicBuffer::USAGE_HW_COMPOSER;
767     return usage;
768 }
769
770 void Layer::updateTransformHint() const {
771     uint32_t orientation = 0;
772     if (!mFlinger->mDebugDisableTransformHint) {
773         // The transform hint is used to improve performance on the main
774         // display -- we can only have a single transform hint, it cannot
775         // apply to all displays.
776         // This is why we use the default display here. This is not an
777         // oversight.
778         sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
779         const Transform& planeTransform(hw->getTransform());
780         orientation = planeTransform.getOrientation();
781         if (orientation & Transform::ROT_INVALID) {
782             orientation = 0;
783         }
784     }
785     mSurfaceTexture->setTransformHint(orientation);
786 }
787
788 // ---------------------------------------------------------------------------
789
790
791 }; // namespace android