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 "Colorizer.h"
40 #include "DisplayDevice.h"
41 #include "Layer.h"
42 #include "SurfaceFlinger.h"
43 #include "SurfaceTextureLayer.h"
44
45 #include "DisplayHardware/HWComposer.h"
46
47 #include "RenderEngine/RenderEngine.h"
48
49 #define DEBUG_RESIZE 0
50
51 namespace android {
52
53 // ---------------------------------------------------------------------------
54
55 int32_t Layer::sSequence = 1;
56
Layer(SurfaceFlinger * flinger,const sp<Client> & client,const String8 & name,uint32_t w,uint32_t h,uint32_t flags)57 Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
58 const String8& name, uint32_t w, uint32_t h, uint32_t flags)
59 : contentDirty(false),
60 sequence(uint32_t(android_atomic_inc(&sSequence))),
61 mFlinger(flinger),
62 mTextureName(-1U),
63 mPremultipliedAlpha(true),
64 mName("unnamed"),
65 mDebug(false),
66 mFormat(PIXEL_FORMAT_NONE),
67 mOpaqueLayer(true),
68 mTransactionFlags(0),
69 mQueuedFrames(0),
70 mCurrentTransform(0),
71 mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
72 mCurrentOpacity(true),
73 mRefreshPending(false),
74 mFrameLatencyNeeded(false),
75 mFiltering(false),
76 mNeedsFiltering(false),
77 mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
78 mSecure(false),
79 mProtectedByApp(false),
80 mHasSurface(false),
81 mClientRef(client)
82 {
83 mCurrentCrop.makeInvalid();
84 mFlinger->getRenderEngine().genTextures(1, &mTextureName);
85 mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
86
87 uint32_t layerFlags = 0;
88 if (flags & ISurfaceComposerClient::eHidden)
89 layerFlags = layer_state_t::eLayerHidden;
90
91 if (flags & ISurfaceComposerClient::eNonPremultiplied)
92 mPremultipliedAlpha = false;
93
94 mName = name;
95
96 mCurrentState.active.w = w;
97 mCurrentState.active.h = h;
98 mCurrentState.active.crop.makeInvalid();
99 mCurrentState.z = 0;
100 mCurrentState.alpha = 0xFF;
101 mCurrentState.layerStack = 0;
102 mCurrentState.flags = layerFlags;
103 mCurrentState.sequence = 0;
104 mCurrentState.transform.set(0, 0);
105 mCurrentState.requested = mCurrentState.active;
106
107 // drawing state & current state are identical
108 mDrawingState = mCurrentState;
109
110 nsecs_t displayPeriod =
111 flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
112 mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
113 }
114
onFirstRef()115 void Layer::onFirstRef() {
116 // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
117 mBufferQueue = new SurfaceTextureLayer(mFlinger);
118 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mBufferQueue, mTextureName);
119 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
120 mSurfaceFlingerConsumer->setFrameAvailableListener(this);
121 mSurfaceFlingerConsumer->setName(mName);
122
123 #ifdef TARGET_DISABLE_TRIPLE_BUFFERING
124 #warning "disabling triple buffering"
125 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
126 #else
127 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
128 #endif
129
130 const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
131 updateTransformHint(hw);
132 }
133
~Layer()134 Layer::~Layer() {
135 sp<Client> c(mClientRef.promote());
136 if (c != 0) {
137 c->detachLayer(this);
138 }
139 mFlinger->deleteTextureAsync(mTextureName);
140 mFrameTracker.logAndResetStats(mName);
141 }
142
143 // ---------------------------------------------------------------------------
144 // callbacks
145 // ---------------------------------------------------------------------------
146
onLayerDisplayed(const sp<const DisplayDevice> & hw,HWComposer::HWCLayerInterface * layer)147 void Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw,
148 HWComposer::HWCLayerInterface* layer) {
149 if (layer) {
150 layer->onDisplayed();
151 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
152 }
153 }
154
onFrameAvailable()155 void Layer::onFrameAvailable() {
156 android_atomic_inc(&mQueuedFrames);
157 mFlinger->signalLayerUpdate();
158 }
159
160 // called with SurfaceFlinger::mStateLock from the drawing thread after
161 // the layer has been remove from the current state list (and just before
162 // it's removed from the drawing state list)
onRemoved()163 void Layer::onRemoved() {
164 mSurfaceFlingerConsumer->abandon();
165 }
166
167 // ---------------------------------------------------------------------------
168 // set-up
169 // ---------------------------------------------------------------------------
170
getName() const171 const String8& Layer::getName() const {
172 return mName;
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 uint32_t const maxSurfaceDims = min(
179 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
180
181 // never allow a surface larger than what our underlying GL implementation
182 // can handle.
183 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
184 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
185 return BAD_VALUE;
186 }
187
188 mFormat = format;
189
190 mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
191 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
192 mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque);
193 mCurrentOpacity = getOpacityForFormat(format);
194
195 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
196 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
197 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
198
199 return NO_ERROR;
200 }
201
getHandle()202 sp<IBinder> Layer::getHandle() {
203 Mutex::Autolock _l(mLock);
204
205 LOG_ALWAYS_FATAL_IF(mHasSurface,
206 "Layer::getHandle() has already been called");
207
208 mHasSurface = true;
209
210 /*
211 * The layer handle is just a BBinder object passed to the client
212 * (remote process) -- we don't keep any reference on our side such that
213 * the dtor is called when the remote side let go of its reference.
214 *
215 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
216 * this layer when the handle is destroyed.
217 */
218
219 class Handle : public BBinder, public LayerCleaner {
220 wp<const Layer> mOwner;
221 public:
222 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
223 : LayerCleaner(flinger, layer), mOwner(layer) {
224 }
225 };
226
227 return new Handle(mFlinger, this);
228 }
229
getBufferQueue() const230 sp<IGraphicBufferProducer> Layer::getBufferQueue() const {
231 return mBufferQueue;
232 }
233
234 // ---------------------------------------------------------------------------
235 // h/w composer set-up
236 // ---------------------------------------------------------------------------
237
getContentCrop() const238 Rect Layer::getContentCrop() const {
239 // this is the crop rectangle that applies to the buffer
240 // itself (as opposed to the window)
241 Rect crop;
242 if (!mCurrentCrop.isEmpty()) {
243 // if the buffer crop is defined, we use that
244 crop = mCurrentCrop;
245 } else if (mActiveBuffer != NULL) {
246 // otherwise we use the whole buffer
247 crop = mActiveBuffer->getBounds();
248 } else {
249 // if we don't have a buffer yet, we use an empty/invalid crop
250 crop.makeInvalid();
251 }
252 return crop;
253 }
254
reduce(const Rect & win,const Region & exclude)255 static Rect reduce(const Rect& win, const Region& exclude) {
256 if (CC_LIKELY(exclude.isEmpty())) {
257 return win;
258 }
259 if (exclude.isRect()) {
260 return win.reduce(exclude.getBounds());
261 }
262 return Region(win).subtract(exclude).getBounds();
263 }
264
computeBounds() const265 Rect Layer::computeBounds() const {
266 const Layer::State& s(getDrawingState());
267 Rect win(s.active.w, s.active.h);
268 if (!s.active.crop.isEmpty()) {
269 win.intersect(s.active.crop, &win);
270 }
271 // subtract the transparent region and snap to the bounds
272 return reduce(win, s.activeTransparentRegion);
273 }
274
computeCrop(const sp<const DisplayDevice> & hw) const275 FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
276 // the content crop is the area of the content that gets scaled to the
277 // layer's size.
278 FloatRect crop(getContentCrop());
279
280 // the active.crop is the area of the window that gets cropped, but not
281 // scaled in any ways.
282 const State& s(getDrawingState());
283
284 // apply the projection's clipping to the window crop in
285 // layerstack space, and convert-back to layer space.
286 // if there are no window scaling involved, this operation will map to full
287 // pixels in the buffer.
288 // FIXME: the 3 lines below can produce slightly incorrect clipping when we have
289 // a viewport clipping and a window transform. we should use floating point to fix this.
290
291 Rect activeCrop(s.active.w, s.active.h);
292 if (!s.active.crop.isEmpty()) {
293 activeCrop = s.active.crop;
294 }
295
296 activeCrop = s.transform.transform(activeCrop);
297 activeCrop.intersect(hw->getViewport(), &activeCrop);
298 activeCrop = s.transform.inverse().transform(activeCrop);
299
300 // paranoia: make sure the window-crop is constrained in the
301 // window's bounds
302 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
303
304 // subtract the transparent region and snap to the bounds
305 activeCrop = reduce(activeCrop, s.activeTransparentRegion);
306
307 if (!activeCrop.isEmpty()) {
308 // Transform the window crop to match the buffer coordinate system,
309 // which means using the inverse of the current transform set on the
310 // SurfaceFlingerConsumer.
311 uint32_t invTransform = mCurrentTransform;
312 int winWidth = s.active.w;
313 int winHeight = s.active.h;
314 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
315 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
316 NATIVE_WINDOW_TRANSFORM_FLIP_H;
317 winWidth = s.active.h;
318 winHeight = s.active.w;
319 }
320 const Rect winCrop = activeCrop.transform(
321 invTransform, s.active.w, s.active.h);
322
323 // below, crop is intersected with winCrop expressed in crop's coordinate space
324 float xScale = crop.getWidth() / float(winWidth);
325 float yScale = crop.getHeight() / float(winHeight);
326
327 float insetL = winCrop.left * xScale;
328 float insetT = winCrop.top * yScale;
329 float insetR = (winWidth - winCrop.right ) * xScale;
330 float insetB = (winHeight - winCrop.bottom) * yScale;
331
332 crop.left += insetL;
333 crop.top += insetT;
334 crop.right -= insetR;
335 crop.bottom -= insetB;
336 }
337 return crop;
338 }
339
setGeometry(const sp<const DisplayDevice> & hw,HWComposer::HWCLayerInterface & layer)340 void Layer::setGeometry(
341 const sp<const DisplayDevice>& hw,
342 HWComposer::HWCLayerInterface& layer)
343 {
344 layer.setDefaultState();
345
346 // enable this layer
347 layer.setSkip(false);
348
349 if (isSecure() && !hw->isSecure()) {
350 layer.setSkip(true);
351 }
352
353 // this gives us only the "orientation" component of the transform
354 const State& s(getDrawingState());
355 if (!isOpaque() || s.alpha != 0xFF) {
356 layer.setBlending(mPremultipliedAlpha ?
357 HWC_BLENDING_PREMULT :
358 HWC_BLENDING_COVERAGE);
359 }
360
361 // apply the layer's transform, followed by the display's global transform
362 // here we're guaranteed that the layer's transform preserves rects
363 Rect frame(s.transform.transform(computeBounds()));
364 frame.intersect(hw->getViewport(), &frame);
365 const Transform& tr(hw->getTransform());
366 layer.setFrame(tr.transform(frame));
367 layer.setCrop(computeCrop(hw));
368 layer.setPlaneAlpha(s.alpha);
369
370 /*
371 * Transformations are applied in this order:
372 * 1) buffer orientation/flip/mirror
373 * 2) state transformation (window manager)
374 * 3) layer orientation (screen orientation)
375 * (NOTE: the matrices are multiplied in reverse order)
376 */
377
378 const Transform bufferOrientation(mCurrentTransform);
379 Transform transform(tr * s.transform * bufferOrientation);
380
381 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
382 /*
383 * the code below applies the display's inverse transform to the buffer
384 */
385 uint32_t invTransform = hw->getOrientationTransform();
386 // calculate the inverse transform
387 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
388 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
389 NATIVE_WINDOW_TRANSFORM_FLIP_H;
390 }
391 // and apply to the current transform
392 transform = transform * Transform(invTransform);
393 }
394
395 // this gives us only the "orientation" component of the transform
396 const uint32_t orientation = transform.getOrientation();
397 if (orientation & Transform::ROT_INVALID) {
398 // we can only handle simple transformation
399 layer.setSkip(true);
400 } else {
401 layer.setTransform(orientation);
402 }
403 }
404
setPerFrameData(const sp<const DisplayDevice> & hw,HWComposer::HWCLayerInterface & layer)405 void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
406 HWComposer::HWCLayerInterface& layer) {
407 // we have to set the visible region on every frame because
408 // we currently free it during onLayerDisplayed(), which is called
409 // after HWComposer::commit() -- every frame.
410 // Apply this display's projection's viewport to the visible region
411 // before giving it to the HWC HAL.
412 const Transform& tr = hw->getTransform();
413 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
414 layer.setVisibleRegionScreen(visible);
415
416 // NOTE: buffer can be NULL if the client never drew into this
417 // layer yet, or if we ran out of memory
418 layer.setBuffer(mActiveBuffer);
419 }
420
setAcquireFence(const sp<const DisplayDevice> & hw,HWComposer::HWCLayerInterface & layer)421 void Layer::setAcquireFence(const sp<const DisplayDevice>& hw,
422 HWComposer::HWCLayerInterface& layer) {
423 int fenceFd = -1;
424
425 // TODO: there is a possible optimization here: we only need to set the
426 // acquire fence the first time a new buffer is acquired on EACH display.
427
428 if (layer.getCompositionType() == HWC_OVERLAY) {
429 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
430 if (fence->isValid()) {
431 fenceFd = fence->dup();
432 if (fenceFd == -1) {
433 ALOGW("failed to dup layer fence, skipping sync: %d", errno);
434 }
435 }
436 }
437 layer.setAcquireFenceFd(fenceFd);
438 }
439
440 // ---------------------------------------------------------------------------
441 // drawing...
442 // ---------------------------------------------------------------------------
443
draw(const sp<const DisplayDevice> & hw,const Region & clip) const444 void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
445 onDraw(hw, clip);
446 }
447
draw(const sp<const DisplayDevice> & hw)448 void Layer::draw(const sp<const DisplayDevice>& hw) {
449 onDraw( hw, Region(hw->bounds()) );
450 }
451
onDraw(const sp<const DisplayDevice> & hw,const Region & clip) const452 void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
453 {
454 ATRACE_CALL();
455
456 if (CC_UNLIKELY(mActiveBuffer == 0)) {
457 // the texture has not been created yet, this Layer has
458 // in fact never been drawn into. This happens frequently with
459 // SurfaceView because the WindowManager can't know when the client
460 // has drawn the first time.
461
462 // If there is nothing under us, we paint the screen in black, otherwise
463 // we just skip this update.
464
465 // figure out if there is something below us
466 Region under;
467 const SurfaceFlinger::LayerVector& drawingLayers(
468 mFlinger->mDrawingState.layersSortedByZ);
469 const size_t count = drawingLayers.size();
470 for (size_t i=0 ; i<count ; ++i) {
471 const sp<Layer>& layer(drawingLayers[i]);
472 if (layer.get() == static_cast<Layer const*>(this))
473 break;
474 under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
475 }
476 // if not everything below us is covered, we plug the holes!
477 Region holes(clip.subtract(under));
478 if (!holes.isEmpty()) {
479 clearWithOpenGL(hw, holes, 0, 0, 0, 1);
480 }
481 return;
482 }
483
484 // Bind the current buffer to the GL texture, and wait for it to be
485 // ready for us to draw into.
486 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
487 if (err != NO_ERROR) {
488 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
489 // Go ahead and draw the buffer anyway; no matter what we do the screen
490 // is probably going to have something visibly wrong.
491 }
492
493 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());
494
495 RenderEngine& engine(mFlinger->getRenderEngine());
496
497 if (!blackOutLayer) {
498 // TODO: we could be more subtle with isFixedSize()
499 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
500
501 // Query the texture matrix given our current filtering mode.
502 float textureMatrix[16];
503 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
504 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
505
506 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
507
508 /*
509 * the code below applies the display's inverse transform to the texture transform
510 */
511
512 // create a 4x4 transform matrix from the display transform flags
513 const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1);
514 const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
515 const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
516
517 mat4 tr;
518 uint32_t transform = hw->getOrientationTransform();
519 if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
520 tr = tr * rot90;
521 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
522 tr = tr * flipH;
523 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
524 tr = tr * flipV;
525
526 // calculate the inverse
527 tr = inverse(tr);
528
529 // and finally apply it to the original texture matrix
530 const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
531 memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
532 }
533
534 // Set things up for texturing.
535 mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
536 mTexture.setFiltering(useFiltering);
537 mTexture.setMatrix(textureMatrix);
538
539 engine.setupLayerTexturing(mTexture);
540 } else {
541 engine.setupLayerBlackedOut();
542 }
543 drawWithOpenGL(hw, clip);
544 engine.disableTexturing();
545 }
546
547
clearWithOpenGL(const sp<const DisplayDevice> & hw,const Region & clip,float red,float green,float blue,float alpha) const548 void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
549 float red, float green, float blue, float alpha) const
550 {
551 RenderEngine& engine(mFlinger->getRenderEngine());
552 computeGeometry(hw, mMesh);
553 engine.setupFillWithColor(red, green, blue, alpha);
554 engine.drawMesh(mMesh);
555 }
556
clearWithOpenGL(const sp<const DisplayDevice> & hw,const Region & clip) const557 void Layer::clearWithOpenGL(
558 const sp<const DisplayDevice>& hw, const Region& clip) const {
559 clearWithOpenGL(hw, clip, 0,0,0,0);
560 }
561
drawWithOpenGL(const sp<const DisplayDevice> & hw,const Region & clip) const562 void Layer::drawWithOpenGL(
563 const sp<const DisplayDevice>& hw, const Region& clip) const {
564 const uint32_t fbHeight = hw->getHeight();
565 const State& s(getDrawingState());
566
567 computeGeometry(hw, mMesh);
568
569 /*
570 * NOTE: the way we compute the texture coordinates here produces
571 * different results than when we take the HWC path -- in the later case
572 * the "source crop" is rounded to texel boundaries.
573 * This can produce significantly different results when the texture
574 * is scaled by a large amount.
575 *
576 * The GL code below is more logical (imho), and the difference with
577 * HWC is due to a limitation of the HWC API to integers -- a question
578 * is suspend is whether we should ignore this problem or revert to
579 * GL composition when a buffer scaling is applied (maybe with some
580 * minimal value)? Or, we could make GL behave like HWC -- but this feel
581 * like more of a hack.
582 */
583 const Rect win(computeBounds());
584
585 float left = float(win.left) / float(s.active.w);
586 float top = float(win.top) / float(s.active.h);
587 float right = float(win.right) / float(s.active.w);
588 float bottom = float(win.bottom) / float(s.active.h);
589
590 // TODO: we probably want to generate the texture coords with the mesh
591 // here we assume that we only have 4 vertices
592 Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
593 texCoords[0] = vec2(left, 1.0f - top);
594 texCoords[1] = vec2(left, 1.0f - bottom);
595 texCoords[2] = vec2(right, 1.0f - bottom);
596 texCoords[3] = vec2(right, 1.0f - top);
597
598 RenderEngine& engine(mFlinger->getRenderEngine());
599 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(), s.alpha);
600 engine.drawMesh(mMesh);
601 engine.disableBlending();
602 }
603
setFiltering(bool filtering)604 void Layer::setFiltering(bool filtering) {
605 mFiltering = filtering;
606 }
607
getFiltering() const608 bool Layer::getFiltering() const {
609 return mFiltering;
610 }
611
612 // As documented in libhardware header, formats in the range
613 // 0x100 - 0x1FF are specific to the HAL implementation, and
614 // are known to have no alpha channel
615 // TODO: move definition for device-specific range into
616 // hardware.h, instead of using hard-coded values here.
617 #define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
618
getOpacityForFormat(uint32_t format)619 bool Layer::getOpacityForFormat(uint32_t format) {
620 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
621 return true;
622 }
623 switch (format) {
624 case HAL_PIXEL_FORMAT_RGBA_8888:
625 case HAL_PIXEL_FORMAT_BGRA_8888:
626 case HAL_PIXEL_FORMAT_sRGB_A_8888:
627 return false;
628 }
629 // in all other case, we have no blending (also for unknown formats)
630 return true;
631 }
632
633 // ----------------------------------------------------------------------------
634 // local state
635 // ----------------------------------------------------------------------------
636
computeGeometry(const sp<const DisplayDevice> & hw,Mesh & mesh) const637 void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh) const
638 {
639 const Layer::State& s(getDrawingState());
640 const Transform tr(hw->getTransform() * s.transform);
641 const uint32_t hw_h = hw->getHeight();
642 Rect win(s.active.w, s.active.h);
643 if (!s.active.crop.isEmpty()) {
644 win.intersect(s.active.crop, &win);
645 }
646 // subtract the transparent region and snap to the bounds
647 win = reduce(win, s.activeTransparentRegion);
648
649 Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
650 position[0] = tr.transform(win.left, win.top);
651 position[1] = tr.transform(win.left, win.bottom);
652 position[2] = tr.transform(win.right, win.bottom);
653 position[3] = tr.transform(win.right, win.top);
654 for (size_t i=0 ; i<4 ; i++) {
655 position[i].y = hw_h - position[i].y;
656 }
657 }
658
isOpaque() const659 bool Layer::isOpaque() const
660 {
661 // if we don't have a buffer yet, we're translucent regardless of the
662 // layer's opaque flag.
663 if (mActiveBuffer == 0) {
664 return false;
665 }
666
667 // if the layer has the opaque flag, then we're always opaque,
668 // otherwise we use the current buffer's format.
669 return mOpaqueLayer || mCurrentOpacity;
670 }
671
isProtected() const672 bool Layer::isProtected() const
673 {
674 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
675 return (activeBuffer != 0) &&
676 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
677 }
678
isFixedSize() const679 bool Layer::isFixedSize() const {
680 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
681 }
682
isCropped() const683 bool Layer::isCropped() const {
684 return !mCurrentCrop.isEmpty();
685 }
686
needsFiltering(const sp<const DisplayDevice> & hw) const687 bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
688 return mNeedsFiltering || hw->needsFiltering();
689 }
690
setVisibleRegion(const Region & visibleRegion)691 void Layer::setVisibleRegion(const Region& visibleRegion) {
692 // always called from main thread
693 this->visibleRegion = visibleRegion;
694 }
695
setCoveredRegion(const Region & coveredRegion)696 void Layer::setCoveredRegion(const Region& coveredRegion) {
697 // always called from main thread
698 this->coveredRegion = coveredRegion;
699 }
700
setVisibleNonTransparentRegion(const Region & setVisibleNonTransparentRegion)701 void Layer::setVisibleNonTransparentRegion(const Region&
702 setVisibleNonTransparentRegion) {
703 // always called from main thread
704 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
705 }
706
707 // ----------------------------------------------------------------------------
708 // transaction
709 // ----------------------------------------------------------------------------
710
doTransaction(uint32_t flags)711 uint32_t Layer::doTransaction(uint32_t flags) {
712 ATRACE_CALL();
713
714 const Layer::State& s(getDrawingState());
715 const Layer::State& c(getCurrentState());
716
717 const bool sizeChanged = (c.requested.w != s.requested.w) ||
718 (c.requested.h != s.requested.h);
719
720 if (sizeChanged) {
721 // the size changed, we need to ask our client to request a new buffer
722 ALOGD_IF(DEBUG_RESIZE,
723 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
724 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
725 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n"
726 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
727 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
728 this, getName().string(), mCurrentTransform, mCurrentScalingMode,
729 c.active.w, c.active.h,
730 c.active.crop.left,
731 c.active.crop.top,
732 c.active.crop.right,
733 c.active.crop.bottom,
734 c.active.crop.getWidth(),
735 c.active.crop.getHeight(),
736 c.requested.w, c.requested.h,
737 c.requested.crop.left,
738 c.requested.crop.top,
739 c.requested.crop.right,
740 c.requested.crop.bottom,
741 c.requested.crop.getWidth(),
742 c.requested.crop.getHeight(),
743 s.active.w, s.active.h,
744 s.active.crop.left,
745 s.active.crop.top,
746 s.active.crop.right,
747 s.active.crop.bottom,
748 s.active.crop.getWidth(),
749 s.active.crop.getHeight(),
750 s.requested.w, s.requested.h,
751 s.requested.crop.left,
752 s.requested.crop.top,
753 s.requested.crop.right,
754 s.requested.crop.bottom,
755 s.requested.crop.getWidth(),
756 s.requested.crop.getHeight());
757
758 // record the new size, form this point on, when the client request
759 // a buffer, it'll get the new size.
760 mSurfaceFlingerConsumer->setDefaultBufferSize(
761 c.requested.w, c.requested.h);
762 }
763
764 if (!isFixedSize()) {
765
766 const bool resizePending = (c.requested.w != c.active.w) ||
767 (c.requested.h != c.active.h);
768
769 if (resizePending) {
770 // don't let Layer::doTransaction update the drawing state
771 // if we have a pending resize, unless we are in fixed-size mode.
772 // the drawing state will be updated only once we receive a buffer
773 // with the correct size.
774 //
775 // in particular, we want to make sure the clip (which is part
776 // of the geometry state) is latched together with the size but is
777 // latched immediately when no resizing is involved.
778
779 flags |= eDontUpdateGeometryState;
780 }
781 }
782
783 // always set active to requested, unless we're asked not to
784 // this is used by Layer, which special cases resizes.
785 if (flags & eDontUpdateGeometryState) {
786 } else {
787 Layer::State& editCurrentState(getCurrentState());
788 editCurrentState.active = c.requested;
789 }
790
791 if (s.active != c.active) {
792 // invalidate and recompute the visible regions if needed
793 flags |= Layer::eVisibleRegion;
794 }
795
796 if (c.sequence != s.sequence) {
797 // invalidate and recompute the visible regions if needed
798 flags |= eVisibleRegion;
799 this->contentDirty = true;
800
801 // we may use linear filtering, if the matrix scales us
802 const uint8_t type = c.transform.getType();
803 mNeedsFiltering = (!c.transform.preserveRects() ||
804 (type >= Transform::SCALE));
805 }
806
807 // Commit the transaction
808 commitTransaction();
809 return flags;
810 }
811
commitTransaction()812 void Layer::commitTransaction() {
813 mDrawingState = mCurrentState;
814 }
815
getTransactionFlags(uint32_t flags)816 uint32_t Layer::getTransactionFlags(uint32_t flags) {
817 return android_atomic_and(~flags, &mTransactionFlags) & flags;
818 }
819
setTransactionFlags(uint32_t flags)820 uint32_t Layer::setTransactionFlags(uint32_t flags) {
821 return android_atomic_or(flags, &mTransactionFlags);
822 }
823
setPosition(float x,float y)824 bool Layer::setPosition(float x, float y) {
825 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
826 return false;
827 mCurrentState.sequence++;
828 mCurrentState.transform.set(x, y);
829 setTransactionFlags(eTransactionNeeded);
830 return true;
831 }
setLayer(uint32_t z)832 bool Layer::setLayer(uint32_t z) {
833 if (mCurrentState.z == z)
834 return false;
835 mCurrentState.sequence++;
836 mCurrentState.z = z;
837 setTransactionFlags(eTransactionNeeded);
838 return true;
839 }
setSize(uint32_t w,uint32_t h)840 bool Layer::setSize(uint32_t w, uint32_t h) {
841 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
842 return false;
843 mCurrentState.requested.w = w;
844 mCurrentState.requested.h = h;
845 setTransactionFlags(eTransactionNeeded);
846 return true;
847 }
setAlpha(uint8_t alpha)848 bool Layer::setAlpha(uint8_t alpha) {
849 if (mCurrentState.alpha == alpha)
850 return false;
851 mCurrentState.sequence++;
852 mCurrentState.alpha = alpha;
853 setTransactionFlags(eTransactionNeeded);
854 return true;
855 }
setMatrix(const layer_state_t::matrix22_t & matrix)856 bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
857 mCurrentState.sequence++;
858 mCurrentState.transform.set(
859 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
860 setTransactionFlags(eTransactionNeeded);
861 return true;
862 }
setTransparentRegionHint(const Region & transparent)863 bool Layer::setTransparentRegionHint(const Region& transparent) {
864 mCurrentState.requestedTransparentRegion = transparent;
865 setTransactionFlags(eTransactionNeeded);
866 return true;
867 }
setFlags(uint8_t flags,uint8_t mask)868 bool Layer::setFlags(uint8_t flags, uint8_t mask) {
869 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
870 if (mCurrentState.flags == newFlags)
871 return false;
872 mCurrentState.sequence++;
873 mCurrentState.flags = newFlags;
874 setTransactionFlags(eTransactionNeeded);
875 return true;
876 }
setCrop(const Rect & crop)877 bool Layer::setCrop(const Rect& crop) {
878 if (mCurrentState.requested.crop == crop)
879 return false;
880 mCurrentState.sequence++;
881 mCurrentState.requested.crop = crop;
882 setTransactionFlags(eTransactionNeeded);
883 return true;
884 }
885
setLayerStack(uint32_t layerStack)886 bool Layer::setLayerStack(uint32_t layerStack) {
887 if (mCurrentState.layerStack == layerStack)
888 return false;
889 mCurrentState.sequence++;
890 mCurrentState.layerStack = layerStack;
891 setTransactionFlags(eTransactionNeeded);
892 return true;
893 }
894
895 // ----------------------------------------------------------------------------
896 // pageflip handling...
897 // ----------------------------------------------------------------------------
898
onPreComposition()899 bool Layer::onPreComposition() {
900 mRefreshPending = false;
901 return mQueuedFrames > 0;
902 }
903
onPostComposition()904 void Layer::onPostComposition() {
905 if (mFrameLatencyNeeded) {
906 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
907 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
908
909 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence();
910 if (frameReadyFence->isValid()) {
911 mFrameTracker.setFrameReadyFence(frameReadyFence);
912 } else {
913 // There was no fence for this frame, so assume that it was ready
914 // to be presented at the desired present time.
915 mFrameTracker.setFrameReadyTime(desiredPresentTime);
916 }
917
918 const HWComposer& hwc = mFlinger->getHwComposer();
919 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
920 if (presentFence->isValid()) {
921 mFrameTracker.setActualPresentFence(presentFence);
922 } else {
923 // The HWC doesn't support present fences, so use the refresh
924 // timestamp instead.
925 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
926 mFrameTracker.setActualPresentTime(presentTime);
927 }
928
929 mFrameTracker.advanceFrame();
930 mFrameLatencyNeeded = false;
931 }
932 }
933
isVisible() const934 bool Layer::isVisible() const {
935 const Layer::State& s(mDrawingState);
936 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
937 && (mActiveBuffer != NULL);
938 }
939
latchBuffer(bool & recomputeVisibleRegions)940 Region Layer::latchBuffer(bool& recomputeVisibleRegions)
941 {
942 ATRACE_CALL();
943
944 Region outDirtyRegion;
945 if (mQueuedFrames > 0) {
946
947 // if we've already called updateTexImage() without going through
948 // a composition step, we have to skip this layer at this point
949 // because we cannot call updateTeximage() without a corresponding
950 // compositionComplete() call.
951 // we'll trigger an update in onPreComposition().
952 if (mRefreshPending) {
953 return outDirtyRegion;
954 }
955
956 // Capture the old state of the layer for comparisons later
957 const bool oldOpacity = isOpaque();
958 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
959
960 struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
961 Layer::State& front;
962 Layer::State& current;
963 bool& recomputeVisibleRegions;
964 Reject(Layer::State& front, Layer::State& current,
965 bool& recomputeVisibleRegions)
966 : front(front), current(current),
967 recomputeVisibleRegions(recomputeVisibleRegions) {
968 }
969
970 virtual bool reject(const sp<GraphicBuffer>& buf,
971 const IGraphicBufferConsumer::BufferItem& item) {
972 if (buf == NULL) {
973 return false;
974 }
975
976 uint32_t bufWidth = buf->getWidth();
977 uint32_t bufHeight = buf->getHeight();
978
979 // check that we received a buffer of the right size
980 // (Take the buffer's orientation into account)
981 if (item.mTransform & Transform::ROT_90) {
982 swap(bufWidth, bufHeight);
983 }
984
985 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
986 if (front.active != front.requested) {
987
988 if (isFixedSize ||
989 (bufWidth == front.requested.w &&
990 bufHeight == front.requested.h))
991 {
992 // Here we pretend the transaction happened by updating the
993 // current and drawing states. Drawing state is only accessed
994 // in this thread, no need to have it locked
995 front.active = front.requested;
996
997 // We also need to update the current state so that
998 // we don't end-up overwriting the drawing state with
999 // this stale current state during the next transaction
1000 //
1001 // NOTE: We don't need to hold the transaction lock here
1002 // because State::active is only accessed from this thread.
1003 current.active = front.active;
1004
1005 // recompute visible region
1006 recomputeVisibleRegions = true;
1007 }
1008
1009 ALOGD_IF(DEBUG_RESIZE,
1010 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n"
1011 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n"
1012 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n",
1013 bufWidth, bufHeight, item.mTransform, item.mScalingMode,
1014 front.active.w, front.active.h,
1015 front.active.crop.left,
1016 front.active.crop.top,
1017 front.active.crop.right,
1018 front.active.crop.bottom,
1019 front.active.crop.getWidth(),
1020 front.active.crop.getHeight(),
1021 front.requested.w, front.requested.h,
1022 front.requested.crop.left,
1023 front.requested.crop.top,
1024 front.requested.crop.right,
1025 front.requested.crop.bottom,
1026 front.requested.crop.getWidth(),
1027 front.requested.crop.getHeight());
1028 }
1029
1030 if (!isFixedSize) {
1031 if (front.active.w != bufWidth ||
1032 front.active.h != bufHeight) {
1033 // reject this buffer
1034 //ALOGD("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
1035 // bufWidth, bufHeight, front.active.w, front.active.h);
1036 return true;
1037 }
1038 }
1039
1040 // if the transparent region has changed (this test is
1041 // conservative, but that's fine, worst case we're doing
1042 // a bit of extra work), we latch the new one and we
1043 // trigger a visible-region recompute.
1044 if (!front.activeTransparentRegion.isTriviallyEqual(
1045 front.requestedTransparentRegion)) {
1046 front.activeTransparentRegion = front.requestedTransparentRegion;
1047
1048 // We also need to update the current state so that
1049 // we don't end-up overwriting the drawing state with
1050 // this stale current state during the next transaction
1051 //
1052 // NOTE: We don't need to hold the transaction lock here
1053 // because State::active is only accessed from this thread.
1054 current.activeTransparentRegion = front.activeTransparentRegion;
1055
1056 // recompute visible region
1057 recomputeVisibleRegions = true;
1058 }
1059
1060 return false;
1061 }
1062 };
1063
1064
1065 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions);
1066
1067 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r);
1068 if (updateResult == BufferQueue::PRESENT_LATER) {
1069 // Producer doesn't want buffer to be displayed yet. Signal a
1070 // layer update so we check again at the next opportunity.
1071 mFlinger->signalLayerUpdate();
1072 return outDirtyRegion;
1073 }
1074
1075 // Decrement the queued-frames count. Signal another event if we
1076 // have more frames pending.
1077 if (android_atomic_dec(&mQueuedFrames) > 1) {
1078 mFlinger->signalLayerUpdate();
1079 }
1080
1081 if (updateResult != NO_ERROR) {
1082 // something happened!
1083 recomputeVisibleRegions = true;
1084 return outDirtyRegion;
1085 }
1086
1087 // update the active buffer
1088 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer();
1089 if (mActiveBuffer == NULL) {
1090 // this can only happen if the very first buffer was rejected.
1091 return outDirtyRegion;
1092 }
1093
1094 mRefreshPending = true;
1095 mFrameLatencyNeeded = true;
1096 if (oldActiveBuffer == NULL) {
1097 // the first time we receive a buffer, we need to trigger a
1098 // geometry invalidation.
1099 recomputeVisibleRegions = true;
1100 }
1101
1102 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
1103 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
1104 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
1105 if ((crop != mCurrentCrop) ||
1106 (transform != mCurrentTransform) ||
1107 (scalingMode != mCurrentScalingMode))
1108 {
1109 mCurrentCrop = crop;
1110 mCurrentTransform = transform;
1111 mCurrentScalingMode = scalingMode;
1112 recomputeVisibleRegions = true;
1113 }
1114
1115 if (oldActiveBuffer != NULL) {
1116 uint32_t bufWidth = mActiveBuffer->getWidth();
1117 uint32_t bufHeight = mActiveBuffer->getHeight();
1118 if (bufWidth != uint32_t(oldActiveBuffer->width) ||
1119 bufHeight != uint32_t(oldActiveBuffer->height)) {
1120 recomputeVisibleRegions = true;
1121 }
1122 }
1123
1124 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
1125 if (oldOpacity != isOpaque()) {
1126 recomputeVisibleRegions = true;
1127 }
1128
1129 // FIXME: postedRegion should be dirty & bounds
1130 const Layer::State& s(getDrawingState());
1131 Region dirtyRegion(Rect(s.active.w, s.active.h));
1132
1133 // transform the dirty region to window-manager space
1134 outDirtyRegion = (s.transform.transform(dirtyRegion));
1135 }
1136 return outDirtyRegion;
1137 }
1138
getEffectiveUsage(uint32_t usage) const1139 uint32_t Layer::getEffectiveUsage(uint32_t usage) const
1140 {
1141 // TODO: should we do something special if mSecure is set?
1142 if (mProtectedByApp) {
1143 // need a hardware-protected path to external video sink
1144 usage |= GraphicBuffer::USAGE_PROTECTED;
1145 }
1146 usage |= GraphicBuffer::USAGE_HW_COMPOSER;
1147 return usage;
1148 }
1149
updateTransformHint(const sp<const DisplayDevice> & hw) const1150 void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
1151 uint32_t orientation = 0;
1152 if (!mFlinger->mDebugDisableTransformHint) {
1153 // The transform hint is used to improve performance, but we can
1154 // only have a single transform hint, it cannot
1155 // apply to all displays.
1156 const Transform& planeTransform(hw->getTransform());
1157 orientation = planeTransform.getOrientation();
1158 if (orientation & Transform::ROT_INVALID) {
1159 orientation = 0;
1160 }
1161 }
1162 mSurfaceFlingerConsumer->setTransformHint(orientation);
1163 }
1164
1165 // ----------------------------------------------------------------------------
1166 // debugging
1167 // ----------------------------------------------------------------------------
1168
dump(String8 & result,Colorizer & colorizer) const1169 void Layer::dump(String8& result, Colorizer& colorizer) const
1170 {
1171 const Layer::State& s(getDrawingState());
1172
1173 colorizer.colorize(result, Colorizer::GREEN);
1174 result.appendFormat(
1175 "+ %s %p (%s)\n",
1176 getTypeId(), this, getName().string());
1177 colorizer.reset(result);
1178
1179 s.activeTransparentRegion.dump(result, "transparentRegion");
1180 visibleRegion.dump(result, "visibleRegion");
1181 sp<Client> client(mClientRef.promote());
1182
1183 result.appendFormat( " "
1184 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
1185 "isOpaque=%1d, invalidate=%1d, "
1186 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
1187 " client=%p\n",
1188 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
1189 s.active.crop.left, s.active.crop.top,
1190 s.active.crop.right, s.active.crop.bottom,
1191 isOpaque(), contentDirty,
1192 s.alpha, s.flags,
1193 s.transform[0][0], s.transform[0][1],
1194 s.transform[1][0], s.transform[1][1],
1195 client.get());
1196
1197 sp<const GraphicBuffer> buf0(mActiveBuffer);
1198 uint32_t w0=0, h0=0, s0=0, f0=0;
1199 if (buf0 != 0) {
1200 w0 = buf0->getWidth();
1201 h0 = buf0->getHeight();
1202 s0 = buf0->getStride();
1203 f0 = buf0->format;
1204 }
1205 result.appendFormat(
1206 " "
1207 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
1208 " queued-frames=%d, mRefreshPending=%d\n",
1209 mFormat, w0, h0, s0,f0,
1210 mQueuedFrames, mRefreshPending);
1211
1212 if (mSurfaceFlingerConsumer != 0) {
1213 mSurfaceFlingerConsumer->dump(result, " ");
1214 }
1215 }
1216
dumpStats(String8 & result) const1217 void Layer::dumpStats(String8& result) const {
1218 mFrameTracker.dump(result);
1219 }
1220
clearStats()1221 void Layer::clearStats() {
1222 mFrameTracker.clear();
1223 }
1224
logFrameStats()1225 void Layer::logFrameStats() {
1226 mFrameTracker.logAndResetStats(mName);
1227 }
1228
1229 // ---------------------------------------------------------------------------
1230
LayerCleaner(const sp<SurfaceFlinger> & flinger,const sp<Layer> & layer)1231 Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
1232 const sp<Layer>& layer)
1233 : mFlinger(flinger), mLayer(layer) {
1234 }
1235
~LayerCleaner()1236 Layer::LayerCleaner::~LayerCleaner() {
1237 // destroy client resources
1238 mFlinger->onLayerDestroyed(mLayer);
1239 }
1240
1241 // ---------------------------------------------------------------------------
1242 }; // namespace android
1243
1244 #if defined(__gl_h_)
1245 #error "don't include gl/gl.h in this file"
1246 #endif
1247
1248 #if defined(__gl2_h_)
1249 #error "don't include gl2/gl2.h in this file"
1250 #endif
1251