mFrameLatencyNeeded(false),
mFiltering(false),
mNeedsFiltering(false),
+ mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
mSecure(false),
mProtectedByApp(false),
mHasSurface(false),
mClientRef(client)
{
mCurrentCrop.makeInvalid();
- glGenTextures(1, &mTextureName);
+ mFlinger->getRenderEngine().genTextures(1, &mTextureName);
+ mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
uint32_t layerFlags = 0;
if (flags & ISurfaceComposerClient::eHidden)
mFrameTracker.setDisplayRefreshPeriod(displayPeriod);
}
-void Layer::onFirstRef()
-{
+void Layer::onFirstRef() {
// Creates a custom BufferQueue for SurfaceFlingerConsumer to use
mBufferQueue = new SurfaceTextureLayer(mFlinger);
- mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mBufferQueue, mTextureName,
- GL_TEXTURE_EXTERNAL_OES, false);
-
+ mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mBufferQueue, mTextureName);
mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
mSurfaceFlingerConsumer->setFrameAvailableListener(this);
mSurfaceFlingerConsumer->setName(mName);
// pixels in the buffer.
// FIXME: the 3 lines below can produce slightly incorrect clipping when we have
// a viewport clipping and a window transform. we should use floating point to fix this.
- Rect activeCrop(s.transform.transform(s.active.crop));
+
+ Rect activeCrop(s.active.w, s.active.h);
+ if (!s.active.crop.isEmpty()) {
+ activeCrop = s.active.crop;
+ }
+
+ activeCrop = s.transform.transform(activeCrop);
activeCrop.intersect(hw->getViewport(), &activeCrop);
activeCrop = s.transform.inverse().transform(activeCrop);
*/
const Transform bufferOrientation(mCurrentTransform);
- const Transform transform(tr * s.transform * bufferOrientation);
+ Transform transform(tr * s.transform * bufferOrientation);
+
+ if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
+ /*
+ * the code below applies the display's inverse transform to the buffer
+ */
+ uint32_t invTransform = hw->getOrientationTransform();
+ // calculate the inverse transform
+ if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
+ invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
+ NATIVE_WINDOW_TRANSFORM_FLIP_H;
+ }
+ // and apply to the current transform
+ transform = transform * Transform(invTransform);
+ }
// this gives us only the "orientation" component of the transform
const uint32_t orientation = transform.getOrientation();
mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
+ if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
+
+ /*
+ * the code below applies the display's inverse transform to the texture transform
+ */
+
+ // create a 4x4 transform matrix from the display transform flags
+ const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1);
+ const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
+ const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
+
+ mat4 tr;
+ uint32_t transform = hw->getOrientationTransform();
+ if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
+ tr = tr * rot90;
+ if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
+ tr = tr * flipH;
+ if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
+ tr = tr * flipV;
+
+ // calculate the inverse
+ tr = inverse(tr);
+
+ // and finally apply it to the original texture matrix
+ const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
+ memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
+ }
+
// Set things up for texturing.
- engine.setupLayerTexturing(mTextureName, useFiltering, textureMatrix);
+ mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
+ mTexture.setFiltering(useFiltering);
+ mTexture.setMatrix(textureMatrix);
+
+ engine.setupLayerTexturing(mTexture);
} else {
engine.setupLayerBlackedOut();
}
void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
- GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) const
+ float red, float green, float blue, float alpha) const
{
- LayerMesh mesh;
- computeGeometry(hw, &mesh);
-
- mFlinger->getRenderEngine().clearWithColor(
- mesh.getVertices(), mesh.getVertexCount(),
- red, green, blue, alpha);
+ RenderEngine& engine(mFlinger->getRenderEngine());
+ computeGeometry(hw, mMesh);
+ engine.setupFillWithColor(red, green, blue, alpha);
+ engine.drawMesh(mMesh);
}
void Layer::clearWithOpenGL(
const uint32_t fbHeight = hw->getHeight();
const State& s(getDrawingState());
- LayerMesh mesh;
- computeGeometry(hw, &mesh);
+ computeGeometry(hw, mMesh);
/*
* NOTE: the way we compute the texture coordinates here produces
*
* The GL code below is more logical (imho), and the difference with
* HWC is due to a limitation of the HWC API to integers -- a question
- * is suspend is wether we should ignore this problem or revert to
+ * is suspend is whether we should ignore this problem or revert to
* GL composition when a buffer scaling is applied (maybe with some
* minimal value)? Or, we could make GL behave like HWC -- but this feel
* like more of a hack.
*/
const Rect win(computeBounds());
- GLfloat left = GLfloat(win.left) / GLfloat(s.active.w);
- GLfloat top = GLfloat(win.top) / GLfloat(s.active.h);
- GLfloat right = GLfloat(win.right) / GLfloat(s.active.w);
- GLfloat bottom = GLfloat(win.bottom) / GLfloat(s.active.h);
+ float left = float(win.left) / float(s.active.w);
+ float top = float(win.top) / float(s.active.h);
+ float right = float(win.right) / float(s.active.w);
+ float bottom = float(win.bottom) / float(s.active.h);
// TODO: we probably want to generate the texture coords with the mesh
// here we assume that we only have 4 vertices
- float texCoords[4][2];
- texCoords[0][0] = left;
- texCoords[0][1] = top;
- texCoords[1][0] = left;
- texCoords[1][1] = bottom;
- texCoords[2][0] = right;
- texCoords[2][1] = bottom;
- texCoords[3][0] = right;
- texCoords[3][1] = top;
- for (int i = 0; i < 4; i++) {
- texCoords[i][1] = 1.0f - texCoords[i][1];
- }
+ Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>());
+ texCoords[0] = vec2(left, 1.0f - top);
+ texCoords[1] = vec2(left, 1.0f - bottom);
+ texCoords[2] = vec2(right, 1.0f - bottom);
+ texCoords[3] = vec2(right, 1.0f - top);
RenderEngine& engine(mFlinger->getRenderEngine());
engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(), s.alpha);
- engine.drawMesh2D(mesh.getVertices(), texCoords, mesh.getVertexCount());
+ engine.drawMesh(mMesh);
engine.disableBlending();
}
switch (format) {
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_BGRA_8888:
+ case HAL_PIXEL_FORMAT_sRGB_A_8888:
return false;
}
// in all other case, we have no blending (also for unknown formats)
// local state
// ----------------------------------------------------------------------------
-void Layer::computeGeometry(const sp<const DisplayDevice>& hw, LayerMesh* mesh) const
+void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh) const
{
const Layer::State& s(getDrawingState());
const Transform tr(hw->getTransform() * s.transform);
}
// subtract the transparent region and snap to the bounds
win = reduce(win, s.activeTransparentRegion);
- if (mesh) {
- tr.transform(mesh->mVertices[0], win.left, win.top);
- tr.transform(mesh->mVertices[1], win.left, win.bottom);
- tr.transform(mesh->mVertices[2], win.right, win.bottom);
- tr.transform(mesh->mVertices[3], win.right, win.top);
- for (size_t i=0 ; i<4 ; i++) {
- mesh->mVertices[i][1] = hw_h - mesh->mVertices[i][1];
- }
+
+ Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
+ position[0] = tr.transform(win.left, win.top);
+ position[1] = tr.transform(win.left, win.bottom);
+ position[2] = tr.transform(win.right, win.bottom);
+ position[3] = tr.transform(win.right, win.top);
+ for (size_t i=0 ; i<4 ; i++) {
+ position[i].y = hw_h - position[i].y;
}
}
if (front.active.w != bufWidth ||
front.active.h != bufHeight) {
// reject this buffer
+ //ALOGD("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}",
+ // bufWidth, bufHeight, front.active.w, front.active.h);
return true;
}
}
}
// ---------------------------------------------------------------------------
+}; // namespace android
+#if defined(__gl_h_)
+#error "don't include gl/gl.h in this file"
+#endif
-}; // namespace android
+#if defined(__gl2_h_)
+#error "don't include gl2/gl2.h in this file"
+#endif