OSDN Git Service

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