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