blob: db2b20eaaf15cacb22d3450840cf09ce54ee17f8 [file] [log] [blame]
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001/*
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
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080017#include <stdlib.h>
18#include <stdint.h>
19#include <sys/types.h>
Mathias Agopiana8bca8d2013-02-27 22:03:19 -080020#include <math.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080021
22#include <utils/Errors.h>
23#include <utils/Log.h>
Mathias Agopian310f8da2009-05-22 01:27:01 -070024#include <binder/IPCThreadState.h>
25#include <binder/IServiceManager.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080026
27#include <GLES/gl.h>
28#include <GLES/glext.h>
29
30#include <hardware/hardware.h>
31
32#include "clz.h"
Mathias Agopiandb403e82012-06-18 16:47:56 -070033#include "Client.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080034#include "LayerBase.h"
Mathias Agopian921e6ac2012-07-23 23:11:29 -070035#include "Layer.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080036#include "SurfaceFlinger.h"
Mathias Agopian0f2f5ff2012-07-31 23:09:07 -070037#include "DisplayDevice.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080038
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080039namespace android {
40
41// ---------------------------------------------------------------------------
42
Mathias Agopianf6679fc2010-08-10 18:09:09 -070043int32_t LayerBase::sSequence = 1;
44
Mathias Agopian3ee454a2012-08-27 16:28:24 -070045LayerBase::LayerBase(SurfaceFlinger* flinger)
46 : contentDirty(false),
Mathias Agopianf6679fc2010-08-10 18:09:09 -070047 sequence(uint32_t(android_atomic_inc(&sSequence))),
Mathias Agopiana67932f2011-04-20 14:20:59 -070048 mFlinger(flinger), mFiltering(false),
Mathias Agopiana2f4e562012-04-15 23:34:59 -070049 mNeedsFiltering(false),
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080050 mTransactionFlags(0),
Mathias Agopian99ce5cd2012-01-31 18:24:27 -080051 mPremultipliedAlpha(true), mName("unnamed"), mDebug(false)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080052{
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080053}
54
55LayerBase::~LayerBase()
56{
57}
58
Mathias Agopiand1296592010-03-09 19:17:47 -080059void LayerBase::setName(const String8& name) {
60 mName = name;
61}
62
63String8 LayerBase::getName() const {
64 return mName;
65}
66
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080067void LayerBase::initStates(uint32_t w, uint32_t h, uint32_t flags)
68{
69 uint32_t layerFlags = 0;
Mathias Agopian3165cc22012-08-08 19:42:09 -070070 if (flags & ISurfaceComposerClient::eHidden)
71 layerFlags = layer_state_t::eLayerHidden;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080072
Mathias Agopian3165cc22012-08-08 19:42:09 -070073 if (flags & ISurfaceComposerClient::eNonPremultiplied)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080074 mPremultipliedAlpha = false;
75
Mathias Agopian93ffb862012-05-16 17:07:49 -070076 mCurrentState.active.w = w;
77 mCurrentState.active.h = h;
78 mCurrentState.active.crop.makeInvalid();
79 mCurrentState.z = 0;
80 mCurrentState.alpha = 0xFF;
Mathias Agopian87855782012-07-24 21:41:09 -070081 mCurrentState.layerStack = 0;
Mathias Agopian93ffb862012-05-16 17:07:49 -070082 mCurrentState.flags = layerFlags;
83 mCurrentState.sequence = 0;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080084 mCurrentState.transform.set(0, 0);
Mathias Agopian93ffb862012-05-16 17:07:49 -070085 mCurrentState.requested = mCurrentState.active;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080086
87 // drawing state & current state are identical
88 mDrawingState = mCurrentState;
89}
90
Mathias Agopianeba8c682012-09-19 23:14:45 -070091bool LayerBase::needsFiltering(const sp<const DisplayDevice>& hw) const {
92 return mNeedsFiltering || hw->needsFiltering();
93}
94
Mathias Agopianba6be542009-09-29 22:32:36 -070095void LayerBase::commitTransaction() {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080096 mDrawingState = mCurrentState;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080097}
98void LayerBase::forceVisibilityTransaction() {
99 // this can be called without SurfaceFlinger.mStateLock, but if we
100 // can atomically increment the sequence number, it doesn't matter.
101 android_atomic_inc(&mCurrentState.sequence);
102 requestTransaction();
103}
104bool LayerBase::requestTransaction() {
105 int32_t old = setTransactionFlags(eTransactionNeeded);
106 return ((old & eTransactionNeeded) == 0);
107}
108uint32_t LayerBase::getTransactionFlags(uint32_t flags) {
109 return android_atomic_and(~flags, &mTransactionFlags) & flags;
110}
111uint32_t LayerBase::setTransactionFlags(uint32_t flags) {
112 return android_atomic_or(flags, &mTransactionFlags);
113}
114
Mathias Agopian41b6aab2011-08-30 18:51:54 -0700115bool LayerBase::setPosition(float x, float y) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800116 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
117 return false;
118 mCurrentState.sequence++;
119 mCurrentState.transform.set(x, y);
120 requestTransaction();
121 return true;
122}
123bool LayerBase::setLayer(uint32_t z) {
124 if (mCurrentState.z == z)
125 return false;
126 mCurrentState.sequence++;
127 mCurrentState.z = z;
128 requestTransaction();
129 return true;
130}
131bool LayerBase::setSize(uint32_t w, uint32_t h) {
Mathias Agopian93ffb862012-05-16 17:07:49 -0700132 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800133 return false;
Mathias Agopian93ffb862012-05-16 17:07:49 -0700134 mCurrentState.requested.w = w;
135 mCurrentState.requested.h = h;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800136 requestTransaction();
137 return true;
138}
139bool LayerBase::setAlpha(uint8_t alpha) {
140 if (mCurrentState.alpha == alpha)
141 return false;
142 mCurrentState.sequence++;
143 mCurrentState.alpha = alpha;
144 requestTransaction();
145 return true;
146}
147bool LayerBase::setMatrix(const layer_state_t::matrix22_t& matrix) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800148 mCurrentState.sequence++;
149 mCurrentState.transform.set(
150 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
151 requestTransaction();
152 return true;
153}
154bool LayerBase::setTransparentRegionHint(const Region& transparent) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800155 mCurrentState.sequence++;
156 mCurrentState.transparentRegion = transparent;
157 requestTransaction();
158 return true;
159}
160bool LayerBase::setFlags(uint8_t flags, uint8_t mask) {
161 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
162 if (mCurrentState.flags == newFlags)
163 return false;
164 mCurrentState.sequence++;
165 mCurrentState.flags = newFlags;
166 requestTransaction();
167 return true;
168}
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700169bool LayerBase::setCrop(const Rect& crop) {
Mathias Agopianb30c4152012-05-16 18:21:32 -0700170 if (mCurrentState.requested.crop == crop)
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700171 return false;
172 mCurrentState.sequence++;
Mathias Agopianb30c4152012-05-16 18:21:32 -0700173 mCurrentState.requested.crop = crop;
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700174 requestTransaction();
175 return true;
176}
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800177
Mathias Agopian87855782012-07-24 21:41:09 -0700178bool LayerBase::setLayerStack(uint32_t layerStack) {
179 if (mCurrentState.layerStack == layerStack)
180 return false;
181 mCurrentState.sequence++;
182 mCurrentState.layerStack = layerStack;
183 requestTransaction();
184 return true;
185}
186
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800187void LayerBase::setVisibleRegion(const Region& visibleRegion) {
188 // always called from main thread
Mathias Agopian4fec8732012-06-29 14:12:52 -0700189 this->visibleRegion = visibleRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800190}
191
192void LayerBase::setCoveredRegion(const Region& coveredRegion) {
193 // always called from main thread
Mathias Agopian4fec8732012-06-29 14:12:52 -0700194 this->coveredRegion = coveredRegion;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800195}
196
Jesse Halla8026d22012-09-25 13:25:04 -0700197void LayerBase::setVisibleNonTransparentRegion(const Region&
198 setVisibleNonTransparentRegion) {
199 // always called from main thread
200 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
201}
202
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800203uint32_t LayerBase::doTransaction(uint32_t flags)
204{
205 const Layer::State& front(drawingState());
206 const Layer::State& temp(currentState());
207
Mathias Agopian05cec9d2012-05-23 14:35:49 -0700208 // always set active to requested, unless we're asked not to
209 // this is used by Layer, which special cases resizes.
210 if (flags & eDontUpdateGeometryState) {
211 } else {
Mathias Agopian7e4a5872009-09-29 22:39:22 -0700212 Layer::State& editTemp(currentState());
Mathias Agopianb30c4152012-05-16 18:21:32 -0700213 editTemp.active = temp.requested;
Mathias Agopian7e4a5872009-09-29 22:39:22 -0700214 }
Mathias Agopian05cec9d2012-05-23 14:35:49 -0700215
Mathias Agopianb30c4152012-05-16 18:21:32 -0700216 if (front.active != temp.active) {
Mathias Agopian6656dbc2009-09-30 12:48:47 -0700217 // invalidate and recompute the visible regions if needed
218 flags |= Layer::eVisibleRegion;
Mathias Agopian6656dbc2009-09-30 12:48:47 -0700219 }
220
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800221 if (temp.sequence != front.sequence) {
222 // invalidate and recompute the visible regions if needed
223 flags |= eVisibleRegion;
224 this->contentDirty = true;
Mathias Agopiana2fe0a22009-09-23 18:34:53 -0700225
Mathias Agopian733189d2010-12-02 21:32:29 -0800226 // we may use linear filtering, if the matrix scales us
227 const uint8_t type = temp.transform.getType();
228 mNeedsFiltering = (!temp.transform.preserveRects() ||
229 (type >= Transform::SCALE));
Mathias Agopiana2fe0a22009-09-23 18:34:53 -0700230 }
231
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800232 // Commit the transaction
Mathias Agopianba6be542009-09-29 22:32:36 -0700233 commitTransaction();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800234 return flags;
235}
236
Mathias Agopian42977342012-08-05 00:40:46 -0700237void LayerBase::computeGeometry(const sp<const DisplayDevice>& hw, LayerMesh* mesh) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800238{
239 const Layer::State& s(drawingState());
Mathias Agopian42977342012-08-05 00:40:46 -0700240 const Transform tr(hw->getTransform() * s.transform);
241 const uint32_t hw_h = hw->getHeight();
Mathias Agopian93ffb862012-05-16 17:07:49 -0700242 Rect win(s.active.w, s.active.h);
Mathias Agopiana046dd92012-09-24 22:01:01 -0700243 if (!s.active.crop.isEmpty()) {
244 win.intersect(s.active.crop, &win);
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700245 }
Mathias Agopian4fec8732012-06-29 14:12:52 -0700246 if (mesh) {
247 tr.transform(mesh->mVertices[0], win.left, win.top);
248 tr.transform(mesh->mVertices[1], win.left, win.bottom);
249 tr.transform(mesh->mVertices[2], win.right, win.bottom);
250 tr.transform(mesh->mVertices[3], win.right, win.top);
251 for (size_t i=0 ; i<4 ; i++) {
252 mesh->mVertices[i][1] = hw_h - mesh->mVertices[i][1];
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800253 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800254 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800255}
256
Mathias Agopian4fec8732012-06-29 14:12:52 -0700257Rect LayerBase::computeBounds() const {
258 const Layer::State& s(drawingState());
Mathias Agopian4fec8732012-06-29 14:12:52 -0700259 Rect win(s.active.w, s.active.h);
Mathias Agopiana046dd92012-09-24 22:01:01 -0700260 if (!s.active.crop.isEmpty()) {
261 win.intersect(s.active.crop, &win);
Mathias Agopian4fec8732012-06-29 14:12:52 -0700262 }
Mathias Agopian5219a062013-02-26 16:37:53 -0800263 return win;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800264}
265
Mathias Agopian4fec8732012-06-29 14:12:52 -0700266Region LayerBase::latchBuffer(bool& recomputeVisibleRegions) {
267 Region result;
268 return result;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800269}
270
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800271
272Rect LayerBase::getContentCrop() const {
273 // regular layers just use their active area as the content crop
274 const State& s(drawingState());
275 return Rect(s.active.w, s.active.h);
276}
277
278uint32_t LayerBase::getContentTransform() const {
279 // regular layers don't have a content transform
280 return 0;
281}
282
283Rect LayerBase::computeCrop(const sp<const DisplayDevice>& hw) const {
Mathias Agopian3da16722013-02-28 17:12:07 -0800284 /*
285 * The way we compute the crop (aka. texture coordinates when we have a
286 * Layer) produces a different output from the GL code in
287 * drawWithOpenGL() due to HWC being limited to integers. The difference
288 * can be large if getContentTransform() contains a large scale factor.
289 * See comments in drawWithOpenGL() for more details.
290 */
291
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800292 // the content crop is the area of the content that gets scaled to the
293 // layer's size.
294 Rect crop(getContentCrop());
295
296 // the active.crop is the area of the window that gets cropped, but not
297 // scaled in any ways.
298 const State& s(drawingState());
Mathias Agopian3da16722013-02-28 17:12:07 -0800299
300 // apply the projection's clipping to the window crop in
301 // layerstack space, and convert-back to layer space.
302 // if there are no window scaling (or content scaling) involved,
303 // this operation will map to full pixels in the buffer.
304 // NOTE: should we revert to GL composition if a scaling is involved
305 // since it cannot be represented in the HWC API?
306 Rect activeCrop(s.transform.transform(s.active.crop));
307 activeCrop.intersect(hw->getViewport(), &activeCrop);
308 activeCrop = s.transform.inverse().transform(activeCrop);
309
310 // paranoia: make sure the window-crop is constrained in the
311 // window's bounds
312 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
313
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800314 if (!activeCrop.isEmpty()) {
315 // Transform the window crop to match the buffer coordinate system,
316 // which means using the inverse of the current transform set on the
317 // SurfaceFlingerConsumer.
318 uint32_t invTransform = getContentTransform();
319 int winWidth = s.active.w;
320 int winHeight = s.active.h;
321 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
322 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
323 NATIVE_WINDOW_TRANSFORM_FLIP_H;
324 winWidth = s.active.h;
325 winHeight = s.active.w;
326 }
327 const Rect winCrop = activeCrop.transform(
328 invTransform, s.active.w, s.active.h);
329
330 // the code below essentially performs a scaled intersection
331 // of crop and winCrop
332 float xScale = float(crop.width()) / float(winWidth);
333 float yScale = float(crop.height()) / float(winHeight);
334
335 int insetL = int(ceilf( winCrop.left * xScale));
336 int insetT = int(ceilf( winCrop.top * yScale));
337 int insetR = int(ceilf((winWidth - winCrop.right ) * xScale));
338 int insetB = int(ceilf((winHeight - winCrop.bottom) * yScale));
339
340 crop.left += insetL;
341 crop.top += insetT;
342 crop.right -= insetR;
343 crop.bottom -= insetB;
344 }
345 return crop;
346}
347
Mathias Agopian4fec8732012-06-29 14:12:52 -0700348void LayerBase::setGeometry(
Mathias Agopian42977342012-08-05 00:40:46 -0700349 const sp<const DisplayDevice>& hw,
Mathias Agopian4fec8732012-06-29 14:12:52 -0700350 HWComposer::HWCLayerInterface& layer)
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700351{
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700352 layer.setDefaultState();
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700353
354 // this gives us only the "orientation" component of the transform
355 const State& s(drawingState());
356 const uint32_t finalTransform = s.transform.getOrientation();
357 // we can only handle simple transformation
358 if (finalTransform & Transform::ROT_INVALID) {
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700359 layer.setTransform(0);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700360 } else {
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700361 layer.setTransform(finalTransform);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700362 }
363
Mathias Agopian9f8386e2013-01-29 18:56:42 -0800364 if (!isOpaque() || s.alpha != 0xFF) {
Mathias Agopian3e8b8532012-05-13 20:42:01 -0700365 layer.setBlending(mPremultipliedAlpha ?
366 HWC_BLENDING_PREMULT :
367 HWC_BLENDING_COVERAGE);
Mathias Agopiana537c0f2011-08-02 15:51:37 -0700368 }
369
Mathias Agopian4fec8732012-06-29 14:12:52 -0700370
Mathias Agopian5219a062013-02-26 16:37:53 -0800371 // apply the layer's transform, followed by the display's global transform
372 // here we're guaranteed that the layer's transform preserves rects
373
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800374 Rect frame(s.transform.transform(computeBounds()));
Mathias Agopian3da16722013-02-28 17:12:07 -0800375 frame.intersect(hw->getViewport(), &frame);
Mathias Agopiana8bca8d2013-02-27 22:03:19 -0800376 const Transform& tr(hw->getTransform());
377 layer.setFrame(tr.transform(frame));
378 layer.setCrop(computeCrop(hw));
Mathias Agopiana350ff92010-08-10 17:14:02 -0700379}
380
Mathias Agopian42977342012-08-05 00:40:46 -0700381void LayerBase::setPerFrameData(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700382 HWComposer::HWCLayerInterface& layer) {
Mathias Agopianc3973602012-08-31 17:51:25 -0700383 // we have to set the visible region on every frame because
384 // we currently free it during onLayerDisplayed(), which is called
385 // after HWComposer::commit() -- every frame.
Mathias Agopianf5f714a2013-02-26 16:54:05 -0800386 // Apply this display's projection's viewport to the visible region
387 // before giving it to the HWC HAL.
Mathias Agopianc3973602012-08-31 17:51:25 -0700388 const Transform& tr = hw->getTransform();
Mathias Agopianf5f714a2013-02-26 16:54:05 -0800389 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
390 layer.setVisibleRegionScreen(visible);
Mathias Agopiana350ff92010-08-10 17:14:02 -0700391}
392
Mathias Agopian42977342012-08-05 00:40:46 -0700393void LayerBase::setAcquireFence(const sp<const DisplayDevice>& hw,
Mathias Agopiand3ee2312012-08-02 14:01:42 -0700394 HWComposer::HWCLayerInterface& layer) {
Jesse Hallc5c5a142012-07-02 16:49:28 -0700395 layer.setAcquireFenceFd(-1);
396}
397
Mathias Agopianc3973602012-08-31 17:51:25 -0700398void LayerBase::onLayerDisplayed(const sp<const DisplayDevice>& hw,
399 HWComposer::HWCLayerInterface* layer) {
400 if (layer) {
401 layer->onDisplayed();
402 }
403}
404
Mathias Agopiana67932f2011-04-20 14:20:59 -0700405void LayerBase::setFiltering(bool filtering)
406{
407 mFiltering = filtering;
408}
409
410bool LayerBase::getFiltering() const
411{
412 return mFiltering;
413}
414
Mathias Agopianda27af92012-09-13 18:17:13 -0700415bool LayerBase::isVisible() const {
416 const Layer::State& s(mDrawingState);
417 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha;
418}
419
Mathias Agopian42977342012-08-05 00:40:46 -0700420void LayerBase::draw(const sp<const DisplayDevice>& hw, const Region& clip) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800421{
Mathias Agopian1b031492012-06-20 17:51:20 -0700422 onDraw(hw, clip);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800423}
424
Mathias Agopian42977342012-08-05 00:40:46 -0700425void LayerBase::draw(const sp<const DisplayDevice>& hw)
Mathias Agopian74c40c02010-09-29 13:02:36 -0700426{
Mathias Agopian42977342012-08-05 00:40:46 -0700427 onDraw( hw, Region(hw->bounds()) );
Mathias Agopian74c40c02010-09-29 13:02:36 -0700428}
429
Mathias Agopian42977342012-08-05 00:40:46 -0700430void LayerBase::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
Mathias Agopian1b031492012-06-20 17:51:20 -0700431 GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800432{
Mathias Agopian42977342012-08-05 00:40:46 -0700433 const uint32_t fbHeight = hw->getHeight();
Mathias Agopian010fccb2010-05-26 22:26:12 -0700434 glColor4f(red,green,blue,alpha);
Mathias Agopian0a917752010-06-14 21:20:00 -0700435
Mathias Agopianc492e672011-10-18 14:49:27 -0700436 glDisable(GL_TEXTURE_EXTERNAL_OES);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700437 glDisable(GL_TEXTURE_2D);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800438 glDisable(GL_BLEND);
Mathias Agopian20f68782009-05-11 00:03:41 -0700439
Mathias Agopian4fec8732012-06-29 14:12:52 -0700440 LayerMesh mesh;
441 computeGeometry(hw, &mesh);
442
443 glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices());
444 glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800445}
446
Mathias Agopian42977342012-08-05 00:40:46 -0700447void LayerBase::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip) const
Rebecca Schultz Zavin29aa74c2009-09-01 23:06:45 -0700448{
Mathias Agopian1b031492012-06-20 17:51:20 -0700449 clearWithOpenGL(hw, clip, 0,0,0,0);
Rebecca Schultz Zavin29aa74c2009-09-01 23:06:45 -0700450}
451
Mathias Agopian42977342012-08-05 00:40:46 -0700452void LayerBase::drawWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip) const
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800453{
Mathias Agopian42977342012-08-05 00:40:46 -0700454 const uint32_t fbHeight = hw->getHeight();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800455 const State& s(drawingState());
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800456
Mathias Agopian49753262010-04-12 15:34:55 -0700457 GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
Glenn Kasten99ed2242011-12-15 09:51:17 -0800458 if (CC_UNLIKELY(s.alpha < 0xFF)) {
Mathias Agopian78fd5012010-04-20 14:51:04 -0700459 const GLfloat alpha = s.alpha * (1.0f/255.0f);
Mathias Agopian49753262010-04-12 15:34:55 -0700460 if (mPremultipliedAlpha) {
461 glColor4f(alpha, alpha, alpha, alpha);
462 } else {
463 glColor4f(1, 1, 1, alpha);
464 }
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800465 glEnable(GL_BLEND);
466 glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
Mathias Agopian49753262010-04-12 15:34:55 -0700467 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800468 } else {
Mathias Agopian78fd5012010-04-20 14:51:04 -0700469 glColor4f(1, 1, 1, 1);
Mathias Agopian49753262010-04-12 15:34:55 -0700470 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
Mathias Agopiana67932f2011-04-20 14:20:59 -0700471 if (!isOpaque()) {
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800472 glEnable(GL_BLEND);
473 glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
474 } else {
475 glDisable(GL_BLEND);
476 }
477 }
478
Mathias Agopian4fec8732012-06-29 14:12:52 -0700479 LayerMesh mesh;
480 computeGeometry(hw, &mesh);
481
482 // TODO: we probably want to generate the texture coords with the mesh
483 // here we assume that we only have 4 vertices
484
Mathias Agopianb661d662010-08-19 17:01:19 -0700485 struct TexCoords {
486 GLfloat u;
487 GLfloat v;
Mathias Agopian78fd5012010-04-20 14:51:04 -0700488 };
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800489
Mathias Agopian3da16722013-02-28 17:12:07 -0800490
491 /*
492 * NOTE: the way we compute the texture coordinates here produces
493 * different results than when we take the HWC path -- in the later case
494 * the "source crop" is rounded to texel boundaries.
495 * This can produce significantly different results when the texture
496 * is scaled by a large amount.
497 *
498 * The GL code below is more logical (imho), and the difference with
499 * HWC is due to a limitation of the HWC API to integers -- a question
500 * is suspend is wether we should ignore this problem or revert to
501 * GL composition when a buffer scaling is applied (maybe with some
502 * minimal value)? Or, we could make GL behave like HWC -- but this feel
503 * like more of a hack.
504 */
505 const Rect win(computeBounds());
Mathias Agopiana046dd92012-09-24 22:01:01 -0700506
507 GLfloat left = GLfloat(win.left) / GLfloat(s.active.w);
508 GLfloat top = GLfloat(win.top) / GLfloat(s.active.h);
509 GLfloat right = GLfloat(win.right) / GLfloat(s.active.w);
510 GLfloat bottom = GLfloat(win.bottom) / GLfloat(s.active.h);
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700511
Mathias Agopianb661d662010-08-19 17:01:19 -0700512 TexCoords texCoords[4];
Jamie Gennisf15a83f2012-05-10 20:43:55 -0700513 texCoords[0].u = left;
514 texCoords[0].v = top;
515 texCoords[1].u = left;
516 texCoords[1].v = bottom;
517 texCoords[2].u = right;
518 texCoords[2].v = bottom;
519 texCoords[3].u = right;
520 texCoords[3].v = top;
521 for (int i = 0; i < 4; i++) {
522 texCoords[i].v = 1.0f - texCoords[i].v;
523 }
Mathias Agopian78fd5012010-04-20 14:51:04 -0700524
525 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
Mathias Agopian78fd5012010-04-20 14:51:04 -0700526 glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
Mathias Agopian4fec8732012-06-29 14:12:52 -0700527 glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices());
528 glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount());
Mathias Agopian78fd5012010-04-20 14:51:04 -0700529
Mathias Agopian78fd5012010-04-20 14:51:04 -0700530 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
Mathias Agopianc492e672011-10-18 14:49:27 -0700531 glDisable(GL_BLEND);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800532}
533
Mathias Agopian1b5e1022010-04-20 17:55:49 -0700534void LayerBase::dump(String8& result, char* buffer, size_t SIZE) const
535{
536 const Layer::State& s(drawingState());
Mathias Agopianc95dbdc2012-02-05 00:19:27 -0800537
538 snprintf(buffer, SIZE,
539 "+ %s %p (%s)\n",
540 getTypeId(), this, getName().string());
541 result.append(buffer);
542
Mathias Agopian82d7ab62012-01-19 18:34:40 -0800543 s.transparentRegion.dump(result, "transparentRegion");
Mathias Agopian4fec8732012-06-29 14:12:52 -0700544 visibleRegion.dump(result, "visibleRegion");
Mathias Agopianc95dbdc2012-02-05 00:19:27 -0800545
Mathias Agopian1b5e1022010-04-20 17:55:49 -0700546 snprintf(buffer, SIZE,
Mathias Agopian1b5e1022010-04-20 17:55:49 -0700547 " "
Mathias Agopian5f20e2d2012-08-10 18:50:38 -0700548 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
Mathias Agopiana67932f2011-04-20 14:20:59 -0700549 "isOpaque=%1d, needsDithering=%1d, invalidate=%1d, "
Mathias Agopian1b5e1022010-04-20 17:55:49 -0700550 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n",
Mathias Agopian791da602012-09-11 20:52:46 -0700551 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
Mathias Agopian93ffb862012-05-16 17:07:49 -0700552 s.active.crop.left, s.active.crop.top,
553 s.active.crop.right, s.active.crop.bottom,
Mathias Agopiana67932f2011-04-20 14:20:59 -0700554 isOpaque(), needsDithering(), contentDirty,
Mathias Agopian1b5e1022010-04-20 17:55:49 -0700555 s.alpha, s.flags,
556 s.transform[0][0], s.transform[0][1],
557 s.transform[1][0], s.transform[1][1]);
558 result.append(buffer);
559}
Mathias Agopian54ba51d2009-10-26 20:12:37 -0700560
Mathias Agopian25e66fc2012-01-28 22:31:55 -0800561void LayerBase::shortDump(String8& result, char* scratch, size_t size) const {
Mathias Agopian48b888a2011-01-19 16:15:53 -0800562 LayerBase::dump(result, scratch, size);
563}
564
Mathias Agopian25e66fc2012-01-28 22:31:55 -0800565void LayerBase::dumpStats(String8& result, char* scratch, size_t SIZE) const {
566}
567
568void LayerBase::clearStats() {
Mathias Agopian82d7ab62012-01-19 18:34:40 -0800569}
Mathias Agopian48b888a2011-01-19 16:15:53 -0800570
Mathias Agopian921e6ac2012-07-23 23:11:29 -0700571sp<LayerBaseClient> LayerBase::getLayerBaseClient() const {
572 return 0;
573}
574
575sp<Layer> LayerBase::getLayer() const {
576 return 0;
577}
578
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800579// ---------------------------------------------------------------------------
580
Mathias Agopian3ee454a2012-08-27 16:28:24 -0700581LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger,
Mathias Agopian96f08192010-06-02 23:28:45 -0700582 const sp<Client>& client)
Mathias Agopian3ee454a2012-08-27 16:28:24 -0700583 : LayerBase(flinger),
Mathias Agopiana1f47b92011-02-15 19:01:06 -0800584 mHasSurface(false),
Mathias Agopianac9fa422013-02-11 16:40:36 -0800585 mClientRef(client)
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800586{
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700587}
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800588
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800589LayerBaseClient::~LayerBaseClient()
590{
Mathias Agopianb7e930d2010-06-01 15:12:58 -0700591 sp<Client> c(mClientRef.promote());
Mathias Agopian96f08192010-06-02 23:28:45 -0700592 if (c != 0) {
Mathias Agopianb7e930d2010-06-01 15:12:58 -0700593 c->detachLayer(this);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800594 }
595}
596
Mathias Agopiana67932f2011-04-20 14:20:59 -0700597sp<ISurface> LayerBaseClient::createSurface()
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800598{
Mathias Agopiana67932f2011-04-20 14:20:59 -0700599 class BSurface : public BnSurface, public LayerCleaner {
Andy McFadden2adaf042012-12-18 09:49:45 -0800600 virtual sp<IGraphicBufferProducer> getSurfaceTexture() const { return 0; }
Mathias Agopiana67932f2011-04-20 14:20:59 -0700601 public:
602 BSurface(const sp<SurfaceFlinger>& flinger,
603 const sp<LayerBaseClient>& layer)
604 : LayerCleaner(flinger, layer) { }
605 };
606 sp<ISurface> sur(new BSurface(mFlinger, this));
607 return sur;
608}
609
610sp<ISurface> LayerBaseClient::getSurface()
611{
612 sp<ISurface> s;
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700613 Mutex::Autolock _l(mLock);
Mathias Agopiana1f47b92011-02-15 19:01:06 -0800614
615 LOG_ALWAYS_FATAL_IF(mHasSurface,
616 "LayerBaseClient::getSurface() has already been called");
617
618 mHasSurface = true;
619 s = createSurface();
620 mClientSurfaceBinder = s->asBinder();
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700621 return s;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800622}
623
Mathias Agopian0d156122011-01-25 20:17:45 -0800624wp<IBinder> LayerBaseClient::getSurfaceBinder() const {
625 return mClientSurfaceBinder;
626}
627
Jamie Gennis582270d2011-08-17 18:19:00 -0700628wp<IBinder> LayerBaseClient::getSurfaceTextureBinder() const {
629 return 0;
630}
631
Mathias Agopian1b5e1022010-04-20 17:55:49 -0700632void LayerBaseClient::dump(String8& result, char* buffer, size_t SIZE) const
633{
634 LayerBase::dump(result, buffer, SIZE);
Mathias Agopianb7e930d2010-06-01 15:12:58 -0700635 sp<Client> client(mClientRef.promote());
Mathias Agopianac9fa422013-02-11 16:40:36 -0800636 snprintf(buffer, SIZE, " client=%p\n", client.get());
Mathias Agopian1b5e1022010-04-20 17:55:49 -0700637 result.append(buffer);
638}
639
Mathias Agopian48b888a2011-01-19 16:15:53 -0800640
641void LayerBaseClient::shortDump(String8& result, char* scratch, size_t size) const
642{
643 LayerBaseClient::dump(result, scratch, size);
644}
645
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700646// ---------------------------------------------------------------------------
647
Mathias Agopiana67932f2011-04-20 14:20:59 -0700648LayerBaseClient::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
649 const sp<LayerBaseClient>& layer)
650 : mFlinger(flinger), mLayer(layer) {
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700651}
652
Mathias Agopiana67932f2011-04-20 14:20:59 -0700653LayerBaseClient::LayerCleaner::~LayerCleaner() {
Mathias Agopian9a112062009-04-17 19:36:26 -0700654 // destroy client resources
Mathias Agopian921e6ac2012-07-23 23:11:29 -0700655 mFlinger->onLayerDestroyed(mLayer);
Mathias Agopianb5b7f262010-05-07 15:58:44 -0700656}
657
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800658// ---------------------------------------------------------------------------
659
660}; // namespace android