void LayerDim::onDraw(const Region& clip) const { const State& s(drawingState()); if (s.alpha>0) { const DisplayHardware& hw(graphicPlane(0).displayHardware()); const GLfloat alpha = s.alpha/255.0f; const uint32_t fbHeight = hw.getHeight(); glDisable(GL_TEXTURE_EXTERNAL_OES); glDisable(GL_TEXTURE_2D); if (s.alpha == 0xFF) { glDisable(GL_BLEND); } else { glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); } glColor4f(0, 0, 0, alpha); glVertexPointer(2, GL_FLOAT, 0, mVertices); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDisable(GL_BLEND); glDisableClientState(GL_TEXTURE_COORD_ARRAY); } }
void LayerBase::drawForSreenShot() { const DisplayHardware& hw(graphicPlane(0).displayHardware()); setFiltering(true); onDraw( Region(hw.bounds()) ); setFiltering(false); }
void Layer::setGeometry(hwc_layer_t* hwcl) { LayerBaseClient::setGeometry(hwcl); hwcl->flags &= ~HWC_SKIP_LAYER; const DisplayHardware& hw(graphicPlane(0).displayHardware()); // we can't do alpha-fade with the hwc HAL. C2D composition // can handle fade cases const State& s(drawingState()); if ((s.alpha < 0xFF) && !(DisplayHardware::C2D_COMPOSITION & hw.getFlags())) { hwcl->flags = HWC_SKIP_LAYER; } hwcl->alpha = s.alpha; /* * Transformations are applied in this order: * 1) buffer orientation/flip/mirror * 2) state transformation (window manager) * 3) layer orientation (screen orientation) * mTransform is already the composition of (2) and (3) * (NOTE: the matrices are multiplied in reverse order) */ const Transform bufferOrientation(mCurrentTransform); const Transform tr(mTransform * bufferOrientation); // this gives us only the "orientation" component of the transform const uint32_t finalTransform = tr.getOrientation(); // we can only handle simple transformation if (finalTransform & Transform::ROT_INVALID) { hwcl->flags = HWC_SKIP_LAYER; } else { hwcl->transform = finalTransform; } if (isCropped()) { hwcl->sourceCrop.left = mCurrentCrop.left; hwcl->sourceCrop.top = mCurrentCrop.top; hwcl->sourceCrop.right = mCurrentCrop.right; hwcl->sourceCrop.bottom = mCurrentCrop.bottom; } else { const sp<GraphicBuffer>& buffer(mActiveBuffer); hwcl->sourceCrop.left = 0; hwcl->sourceCrop.top = 0; if (buffer != NULL) { hwcl->sourceCrop.right = buffer->width; hwcl->sourceCrop.bottom = buffer->height; } else { hwcl->sourceCrop.right = mTransformedBounds.width(); hwcl->sourceCrop.bottom = mTransformedBounds.height(); } } }
void Layer::onLayerDisplayed() { if (mFrameLatencyNeeded) { const DisplayHardware& hw(graphicPlane(0).displayHardware()); mFrameStats[mFrameLatencyOffset].timestamp = mSurfaceTexture->getTimestamp(); mFrameStats[mFrameLatencyOffset].set = systemTime(); mFrameStats[mFrameLatencyOffset].vsync = hw.getRefreshTimestamp(); mFrameLatencyOffset = (mFrameLatencyOffset + 1) % 128; mFrameLatencyNeeded = false; } }
status_t Layer::setBuffers( uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) { // this surfaces pixel format PixelFormatInfo info; status_t err = getPixelFormatInfo(format, &info); if (err) { ALOGE("unsupported pixelformat %d", format); return err; } // the display's pixel format const DisplayHardware& hw(graphicPlane(0).displayHardware()); uint32_t const maxSurfaceDims = min( hw.getMaxTextureSize(), hw.getMaxViewportDims()); // never allow a surface larger than what our underlying GL implementation // can handle. if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) { ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h)); return BAD_VALUE; } PixelFormatInfo displayInfo; getPixelFormatInfo(hw.getFormat(), &displayInfo); const uint32_t hwFlags = hw.getFlags(); mFormat = format; mSecure = (flags & ISurfaceComposer::eSecure) ? true : false; mProtectedByApp = (flags & ISurfaceComposer::eProtectedByApp) ? true : false; mOpaqueLayer = (flags & ISurfaceComposer::eOpaque); mCurrentOpacity = getOpacityForFormat(format); mSurfaceTexture->setDefaultBufferSize(w, h); mSurfaceTexture->setDefaultBufferFormat(format); mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0)); int useDither = mFlinger->getUseDithering(); if (useDither) { if (useDither == 2) { mNeedsDithering = true; } else { // we use the red index int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED); int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED); mNeedsDithering = (layerRedsize > displayRedSize); } } else { mNeedsDithering = false; } return NO_ERROR; }
void LayerBase::drawForSreenShot() { //Dont draw External-only layers if (isLayerExternalOnly(getLayer())) { return; } const DisplayHardware& hw(graphicPlane(0).displayHardware()); setFiltering(true); onDraw( Region(hw.bounds()) ); setFiltering(false); }
void LayerScreenshot::onDraw(const Region& clip) const { const DisplayHardware& hw(graphicPlane(0).displayHardware()); copybit_image_t dst; hw.getDisplaySurface(&dst); if (dst.base != 0) { uint8_t const* src = (uint8_t const*)(intptr_t(dst.base) + dst.offset); const int fbWidth = dst.w; const int fbHeight = dst.h; const int fbFormat = dst.format; int x = mTransformedBounds.left; int y = mTransformedBounds.top; int w = mTransformedBounds.width(); int h = mTransformedBounds.height(); Parcel* const reply = mReply; if (reply) { const size_t Bpp = bytesPerPixel(fbFormat); const size_t size = w * h * Bpp; int32_t cfg = SkBitmap::kNo_Config; switch (fbFormat) { case PIXEL_FORMAT_RGBA_4444: cfg = SkBitmap::kARGB_4444_Config; case PIXEL_FORMAT_RGBA_8888: cfg = SkBitmap::kARGB_8888_Config; case PIXEL_FORMAT_RGB_565: cfg = SkBitmap::kRGB_565_Config; case PIXEL_FORMAT_A_8: cfg = SkBitmap::kA8_Config; } reply->writeInt32(0); reply->writeInt32(cfg); reply->writeInt32(w); reply->writeInt32(h); reply->writeInt32(w * Bpp); void* data = reply->writeInplace(size); if (data) { uint8_t* d = (uint8_t*)data; uint8_t const* s = src + (x + y*fbWidth) * Bpp; if (w == fbWidth) { memcpy(d, s, w*h*Bpp); } else { for (int y=0 ; y<h ; y++) { memcpy(d, s, w*Bpp); d += w*Bpp; s += fbWidth*Bpp; } } } } } mCV.broadcast(); }
void LayerBase::clearWithOpenGL(const Region& clip, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) const { const DisplayHardware& hw(graphicPlane(0).displayHardware()); const uint32_t fbHeight = hw.getHeight(); glColor4f(red,green,blue,alpha); glDisable(GL_TEXTURE_EXTERNAL_OES); glDisable(GL_TEXTURE_2D); glDisable(GL_BLEND); glVertexPointer(2, GL_FLOAT, 0, mVertices); glDrawArrays(GL_TRIANGLE_FAN, 0, mNumVertices); }
void LayerBase::drawRegion(const Region& reg) const { Region::iterator iterator(reg); if (iterator) { Rect r; const DisplayHardware& hw(graphicPlane(0).displayHardware()); const int32_t fbWidth = hw.getWidth(); const int32_t fbHeight = hw.getHeight(); const GLshort vertices[][2] = { { 0, 0 }, { fbWidth, 0 }, { fbWidth, fbHeight }, { 0, fbHeight } }; glVertexPointer(2, GL_SHORT, 0, vertices); while (iterator.iterate(&r)) { const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } } }
void LayerBase::validateVisibility(const Transform& planeTransform) { const Layer::State& s(drawingState()); const Transform tr(planeTransform * s.transform); const bool transformed = tr.transformed(); const DisplayHardware& hw(graphicPlane(0).displayHardware()); const uint32_t hw_h = hw.getHeight(); const Rect& crop(s.active.crop); Rect win(s.active.w, s.active.h); if (!crop.isEmpty()) { win.intersect(crop, &win); } mNumVertices = 4; tr.transform(mVertices[0], win.left, win.top); tr.transform(mVertices[1], win.left, win.bottom); tr.transform(mVertices[2], win.right, win.bottom); tr.transform(mVertices[3], win.right, win.top); for (size_t i=0 ; i<4 ; i++) mVertices[i][1] = hw_h - mVertices[i][1]; if (CC_UNLIKELY(transformed)) { // NOTE: here we could also punt if we have too many rectangles // in the transparent region if (tr.preserveRects()) { // transform the transparent region transparentRegionScreen = tr.transform(s.transparentRegion); } else { // transformation too complex, can't do the transparent region // optimization. transparentRegionScreen.clear(); } } else { transparentRegionScreen = s.transparentRegion; } // cache a few things... mOrientation = tr.getOrientation(); mPlaneOrientation = planeTransform.getOrientation(); mTransform = tr; mTransformedBounds = tr.transform(win); }
void LayerBase::clearWithOpenGL(const Region& clip) const { const DisplayHardware& hw(graphicPlane(0).displayHardware()); const uint32_t fbHeight = hw.getHeight(); glColor4x(0,0,0,0); glDisable(GL_TEXTURE_2D); glDisable(GL_BLEND); glDisable(GL_DITHER); Rect r; Region::iterator iterator(clip); if (iterator) { glVertexPointer(2, GL_FIXED, 0, mVertices); while (iterator.iterate(&r)) { const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } } }
void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const { LayerBaseClient::dumpStats(result, buffer, SIZE); const size_t o = mFrameLatencyOffset; const DisplayHardware& hw(graphicPlane(0).displayHardware()); const nsecs_t period = hw.getRefreshPeriod(); result.appendFormat("%lld\n", period); for (size_t i=0 ; i<128 ; i++) { const size_t index = (o+i) % 128; const nsecs_t time_app = mFrameStats[index].timestamp; const nsecs_t time_set = mFrameStats[index].set; const nsecs_t time_vsync = mFrameStats[index].vsync; result.appendFormat("%lld\t%lld\t%lld\n", time_app, time_vsync, time_set); } result.append("\n"); }
status_t Layer::setBuffers( uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) { // this surfaces pixel format PixelFormatInfo info; status_t err = getPixelFormatInfo(format, &info); if (err) return err; // the display's pixel format const DisplayHardware& hw(graphicPlane(0).displayHardware()); uint32_t const maxSurfaceDims = min( hw.getMaxTextureSize(), hw.getMaxViewportDims()); // never allow a surface larger than what our underlying GL implementation // can handle. if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) { return BAD_VALUE; } PixelFormatInfo displayInfo; getPixelFormatInfo(hw.getFormat(), &displayInfo); const uint32_t hwFlags = hw.getFlags(); mFormat = format; mWidth = w; mHeight = h; mReqFormat = format; mReqWidth = w; mReqHeight = h; mSecure = (flags & ISurfaceComposer::eSecure) ? true : false; mNeedsBlending = (info.h_alpha - info.l_alpha) > 0; // we use the red index int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED); int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED); mNeedsDithering = layerRedsize > displayRedSize; mSurface = new SurfaceLayer(mFlinger, this); return NO_ERROR; }
void LayerBase::validateVisibility(const Transform& planeTransform) { const Layer::State& s(drawingState()); const Transform tr(planeTransform * s.transform); const bool transformed = tr.transformed(); const DisplayHardware& hw(graphicPlane(0).displayHardware()); const uint32_t hw_h = hw.getHeight(); uint32_t w = s.w; uint32_t h = s.h; tr.transform(mVertices[0], 0, 0); tr.transform(mVertices[1], 0, h); tr.transform(mVertices[2], w, h); tr.transform(mVertices[3], w, 0); for (size_t i=0 ; i<4 ; i++) mVertices[i][1] = hw_h - mVertices[i][1]; if (UNLIKELY(transformed)) { // NOTE: here we could also punt if we have too many rectangles // in the transparent region if (tr.preserveRects()) { // transform the transparent region transparentRegionScreen = tr.transform(s.transparentRegion); } else { // transformation too complex, can't do the transparent region // optimization. transparentRegionScreen.clear(); } } else { transparentRegionScreen = s.transparentRegion; } // cache a few things... mOrientation = tr.getOrientation(); mPlaneOrientation = planeTransform.getOrientation(); mTransform = tr; mTransformedBounds = tr.makeBounds(w, h); }
void LayerBase::clearWithOpenGL(const Region& clip, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) const { const DisplayHardware& hw(graphicPlane(0).displayHardware()); const uint32_t fbHeight = hw.getHeight(); glColor4f(red,green,blue,alpha); glDisable(GL_TEXTURE_EXTERNAL_OES); glDisable(GL_TEXTURE_2D); glDisable(GL_BLEND); Region::const_iterator it = clip.begin(); Region::const_iterator const end = clip.end(); glEnable(GL_SCISSOR_TEST); glVertexPointer(2, GL_FLOAT, 0, mVertices); while (it != end) { const Rect& r = *it++; const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } }
void LayerBuffer::drawForSreenShot() const { const DisplayHardware& hw(graphicPlane(0).displayHardware()); clearWithOpenGL( Region(hw.bounds()) ); }
void LayerBlur::onDraw(const Region& clip) const { const DisplayHardware& hw(graphicPlane(0).displayHardware()); const uint32_t fbHeight = hw.getHeight(); int x = mTransformedBounds.left; int y = mTransformedBounds.top; int w = mTransformedBounds.width(); int h = mTransformedBounds.height(); GLint X = x; GLint Y = fbHeight - (y + h); if (X < 0) { w += X; X = 0; } if (Y < 0) { h += Y; Y = 0; } if (w<0 || h<0) { // we're outside of the framebuffer return; } if (mTextureName == -1U) { // create the texture name the first time // can't do that in the ctor, because it runs in another thread. glGenTextures(1, &mTextureName); } Region::iterator iterator(clip); if (iterator) { glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, mTextureName); if (mRefreshCache) { mRefreshCache = false; mAutoRefreshPending = false; // allocate enough memory for 4-bytes (2 pixels) aligned data const int32_t s = (w + 1) & ~1; uint16_t* const pixels = (uint16_t*)malloc(s*h*2); // This reads the frame-buffer, so a h/w GL would have to // finish() its rendering first. we don't want to do that // too often. Read data is 4-bytes aligned. glReadPixels(X, Y, w, h, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels); // blur that texture. GGLSurface bl; bl.version = sizeof(GGLSurface); bl.width = w; bl.height = h; bl.stride = s; bl.format = GGL_PIXEL_FORMAT_RGB_565; bl.data = (GGLubyte*)pixels; blurFilter(&bl, 8, 2); // NOTE: this works only because we have POT. we'd have to round the // texture size up, otherwise. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels); free((void*)pixels); } const State& s = drawingState(); if (UNLIKELY(s.alpha < 0xFF)) { const GGLfixed alpha = (s.alpha << 16)/255; glColor4x(0, 0, 0, alpha); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); } else { glDisable(GL_BLEND); } glDisable(GL_DITHER); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); if (UNLIKELY(transformed() || !(mFlags & DisplayHardware::DRAW_TEXTURE_EXTENSION) )) { // This is a very rare scenario. glMatrixMode(GL_TEXTURE); glLoadIdentity(); glScalef(1.0f/w, -1.0f/h, 1); glTranslatef(-x, -y, 0); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(2, GL_FIXED, 0, mVertices); glTexCoordPointer(2, GL_FIXED, 0, mVertices); Rect r; while (iterator.iterate(&r)) { const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } } else { Region::iterator iterator(clip); if (iterator) { // NOTE: this is marginally faster with the software gl, because // glReadPixels() reads the fb bottom-to-top, however we'll // skip all the jaccobian computations. Rect r; GLint crop[4] = { 0, 0, w, h }; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop); y = fbHeight - (y + h); while (iterator.iterate(&r)) { const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); glDrawTexiOES(x, y, 0, w, h); } } } } glDisableClientState(GL_TEXTURE_COORD_ARRAY); }
void LayerBase::drawWithOpenGL(const Region& clip) const { const DisplayHardware& hw(graphicPlane(0).displayHardware()); const uint32_t fbHeight = hw.getHeight(); const State& s(drawingState()); GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; if (UNLIKELY(s.alpha < 0xFF)) { const GLfloat alpha = s.alpha * (1.0f/255.0f); if (mPremultipliedAlpha) { glColor4f(alpha, alpha, alpha, alpha); } else { glColor4f(1, 1, 1, alpha); } glEnable(GL_BLEND); glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } else { glColor4f(1, 1, 1, 1); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); if (!isOpaque()) { glEnable(GL_BLEND); glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); } else { glDisable(GL_BLEND); } } struct TexCoords { GLfloat u; GLfloat v; }; TexCoords texCoords[4]; texCoords[0].u = 0; texCoords[0].v = 1; texCoords[1].u = 0; texCoords[1].v = 0; texCoords[2].u = 1; texCoords[2].v = 0; texCoords[3].u = 1; texCoords[3].v = 1; if (drawRotatedTexture) { int tWidth = mTransformedBounds.right - mTransformedBounds.left; int val = drawRotatedTexture(mOrientation, tWidth, fbHeight, clip, (GLfloat *) mVertices, (GLfloat *) texCoords); if (val == NO_ERROR) { return; } } glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(2, GL_FLOAT, 0, mVertices); glTexCoordPointer(2, GL_FLOAT, 0, texCoords); Region::const_iterator it = clip.begin(); Region::const_iterator const end = clip.end(); while (it != end) { const Rect& r = *it++; const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisable(GL_BLEND); }
void LayerBase::drawForSreenShot() const { const DisplayHardware& hw(graphicPlane(0).displayHardware()); onDraw( Region(hw.bounds()) ); }
void LayerBlur::onDraw(const Region& clip) const { const DisplayHardware& hw(graphicPlane(0).displayHardware()); const uint32_t fbHeight = hw.getHeight(); int x = mTransformedBounds.left; int y = mTransformedBounds.top; int w = mTransformedBounds.width(); int h = mTransformedBounds.height(); GLint X = x; GLint Y = fbHeight - (y + h); if (X < 0) { w += X; X = 0; } if (Y < 0) { h += Y; Y = 0; } if (w<0 || h<0) { // we're outside of the framebuffer return; } if (mTextureName == -1U) { // create the texture name the first time // can't do that in the ctor, because it runs in another thread. glGenTextures(1, &mTextureName); glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES, &mReadFormat); glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE_OES, &mReadType); if (mReadFormat != GL_RGB || mReadType != GL_UNSIGNED_SHORT_5_6_5) { mReadFormat = GL_RGBA; mReadType = GL_UNSIGNED_BYTE; mBlurFormat = GGL_PIXEL_FORMAT_RGBX_8888; } } Region::const_iterator it = clip.begin(); Region::const_iterator const end = clip.end(); if (it != end) { #if defined(GL_OES_EGL_image_external) if (GLExtensions::getInstance().haveTextureExternal()) { glDisable(GL_TEXTURE_EXTERNAL_OES); } #endif glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, mTextureName); if (mRefreshCache) { mRefreshCache = false; mAutoRefreshPending = false; int32_t pixelSize = 4; int32_t s = w; if (mReadType == GL_UNSIGNED_SHORT_5_6_5) { // allocate enough memory for 4-bytes (2 pixels) aligned data s = (w + 1) & ~1; pixelSize = 2; } uint16_t* const pixels = (uint16_t*)malloc(s*h*pixelSize); // This reads the frame-buffer, so a h/w GL would have to // finish() its rendering first. we don't want to do that // too often. Read data is 4-bytes aligned. glReadPixels(X, Y, w, h, mReadFormat, mReadType, pixels); // blur that texture. GGLSurface bl; bl.version = sizeof(GGLSurface); bl.width = w; bl.height = h; bl.stride = s; bl.format = mBlurFormat; bl.data = (GGLubyte*)pixels; blurFilter(&bl, 8, 2); if (GLExtensions::getInstance().haveNpot()) { glTexImage2D(GL_TEXTURE_2D, 0, mReadFormat, w, h, 0, mReadFormat, mReadType, pixels); mWidthScale = 1.0f / w; mHeightScale =-1.0f / h; mYOffset = 0; } else { GLuint tw = 1 << (31 - clz(w)); GLuint th = 1 << (31 - clz(h)); if (tw < GLuint(w)) tw <<= 1; if (th < GLuint(h)) th <<= 1; glTexImage2D(GL_TEXTURE_2D, 0, mReadFormat, tw, th, 0, mReadFormat, mReadType, NULL); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, mReadFormat, mReadType, pixels); mWidthScale = 1.0f / tw; mHeightScale =-1.0f / th; mYOffset = th-h; } free((void*)pixels); } const State& s = drawingState(); if (UNLIKELY(s.alpha < 0xFF)) { const GLfloat alpha = s.alpha * (1.0f/255.0f); glColor4f(0, 0, 0, alpha); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); } else { glDisable(GL_BLEND); } if (mFlags & DisplayHardware::SLOW_CONFIG) { glDisable(GL_DITHER); } else { glEnable(GL_DITHER); } glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); #ifdef AVOID_DRAW_TEXTURE if(UNLIKELY(transformed())) #endif { glMatrixMode(GL_TEXTURE); glLoadIdentity(); glScalef(mWidthScale, mHeightScale, 1); glTranslatef(-x, mYOffset - y, 0); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(2, GL_FLOAT, 0, mVertices); glTexCoordPointer(2, GL_FLOAT, 0, mVertices); while (it != end) { const Rect& r = *it++; const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } glDisableClientState(GL_TEXTURE_COORD_ARRAY); } #ifdef AVOID_DRAW_TEXTURE else{ Rect r; GLint crop[4] = { 0, 0, w, h }; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop); y = fbHeight - (y + h); while (it != end) { const Rect& r = *it++; const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); glDrawTexiOES(x, y, 0, w, h); } } #endif glLoadIdentity(); glMatrixMode(GL_MODELVIEW); } }
void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const { const DisplayHardware& hw(graphicPlane(0).displayHardware()); const uint32_t fbHeight = hw.getHeight(); const State& s(drawingState()); // bind our texture TextureManager::activateTexture(texture, needsFiltering()); uint32_t width = texture.width; uint32_t height = texture.height; GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; int renderEffect = mFlinger->getRenderEffect(); int renderColorR = mFlinger->getRenderColorR(); int renderColorG = mFlinger->getRenderColorG(); int renderColorB = mFlinger->getRenderColorB(); bool noEffect = renderEffect == 0; if (UNLIKELY(s.alpha < 0xFF) && noEffect) { const GLfloat alpha = s.alpha * (1.0f/255.0f); if (mPremultipliedAlpha) { glColor4f(alpha, alpha, alpha, alpha); } else { glColor4f(1, 1, 1, alpha); } glEnable(GL_BLEND); glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } else if (noEffect) { glColor4f(1, 1, 1, 1); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); if (needsBlending()) { glEnable(GL_BLEND); glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); } else { glDisable(GL_BLEND); } } else { // Apply a render effect, which is simple color masks for now. GLenum env, src; env = GL_MODULATE; src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; const GGLfixed alpha = (s.alpha << 16)/255; switch (renderEffect) { case RENDER_EFFECT_NIGHT: glColor4x(alpha, alpha*0.6204, alpha*0.3018, alpha); break; case RENDER_EFFECT_TERMINAL: glColor4x(0, alpha, 0, alpha); break; case RENDER_EFFECT_BLUE: glColor4x(0, 0, alpha, alpha); break; case RENDER_EFFECT_AMBER: glColor4x(alpha, alpha*0.75, 0, alpha); break; case RENDER_EFFECT_SALMON: glColor4x(alpha, alpha*0.5, alpha*0.5, alpha); break; case RENDER_EFFECT_FUSCIA: glColor4x(alpha, 0, alpha*0.5, alpha); break; case RENDER_EFFECT_N1_CALIBRATED_N: glColor4x(alpha*renderColorR/1000, alpha*renderColorG/1000, alpha*renderColorB/1000, alpha); break; case RENDER_EFFECT_N1_CALIBRATED_R: glColor4x(alpha*(renderColorR-50)/1000, alpha*renderColorG/1000, alpha*(renderColorB-30)/1000, alpha); break; case RENDER_EFFECT_N1_CALIBRATED_C: glColor4x(alpha*renderColorR/1000, alpha*renderColorG/1000, alpha*(renderColorB+30)/1000, alpha); break; case RENDER_EFFECT_RED: glColor4x(alpha, 0, 0, alpha); break; } glEnable(GL_BLEND); glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, env); } /* * compute texture coordinates * here, we handle NPOT, cropping and buffer transformations */ GLfloat cl, ct, cr, cb; if (!mBufferCrop.isEmpty()) { // source is cropped const GLfloat us = (texture.NPOTAdjust ? texture.wScale : 1.0f) / width; const GLfloat vs = (texture.NPOTAdjust ? texture.hScale : 1.0f) / height; cl = mBufferCrop.left * us; ct = mBufferCrop.top * vs; cr = mBufferCrop.right * us; cb = mBufferCrop.bottom * vs; } else { cl = 0; ct = 0; cr = (texture.NPOTAdjust ? texture.wScale : 1.0f); cb = (texture.NPOTAdjust ? texture.hScale : 1.0f); } /* * For the buffer transformation, we apply the rotation last. * Since we're transforming the texture-coordinates, we need * to apply the inverse of the buffer transformation: * inverse( FLIP_V -> FLIP_H -> ROT_90 ) * <=> inverse( ROT_90 * FLIP_H * FLIP_V ) * = inverse(FLIP_V) * inverse(FLIP_H) * inverse(ROT_90) * = FLIP_V * FLIP_H * ROT_270 * <=> ROT_270 -> FLIP_H -> FLIP_V * * The rotation is performed first, in the texture coordinate space. * */ struct TexCoords { GLfloat u; GLfloat v; }; enum { // name of the corners in the texture map LB = 0, // left-bottom LT = 1, // left-top RT = 2, // right-top RB = 3 // right-bottom }; // vertices in screen space int vLT = LB; int vLB = LT; int vRB = RT; int vRT = RB; // the texture's source is rotated uint32_t transform = mBufferTransform; if (transform & HAL_TRANSFORM_ROT_90) { vLT = RB; vLB = LB; vRB = LT; vRT = RT; } if (transform & HAL_TRANSFORM_FLIP_V) { swap(vLT, vLB); swap(vRT, vRB); } if (transform & HAL_TRANSFORM_FLIP_H) { swap(vLT, vRT); swap(vLB, vRB); } TexCoords texCoords[4]; texCoords[vLT].u = cl; texCoords[vLT].v = ct; texCoords[vLB].u = cl; texCoords[vLB].v = cb; texCoords[vRB].u = cr; texCoords[vRB].v = cb; texCoords[vRT].u = cr; texCoords[vRT].v = ct; if (needsDithering()) { glEnable(GL_DITHER); } else { glDisable(GL_DITHER); } glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(2, GL_FLOAT, 0, mVertices); glTexCoordPointer(2, GL_FLOAT, 0, texCoords); Region::const_iterator it = clip.begin(); Region::const_iterator const end = clip.end(); while (it != end) { const Rect& r = *it++; const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } glDisableClientState(GL_TEXTURE_COORD_ARRAY); }
void LayerBase::drawWithOpenGL(const Region& clip, GLint textureName, const GGLSurface& t) const { const DisplayHardware& hw(graphicPlane(0).displayHardware()); const uint32_t fbHeight = hw.getHeight(); const State& s(drawingState()); // bind our texture validateTexture(textureName); glEnable(GL_TEXTURE_2D); // Dithering... if (s.flags & ISurfaceComposer::eLayerDither) { glEnable(GL_DITHER); } else { glDisable(GL_DITHER); } if (UNLIKELY(s.alpha < 0xFF)) { // We have an alpha-modulation. We need to modulate all // texture components by alpha because we're always using // premultiplied alpha. // If the texture doesn't have an alpha channel we can // use REPLACE and switch to non premultiplied alpha // blending (SRCA/ONE_MINUS_SRCA). GLenum env, src; if (needsBlending()) { env = GL_MODULATE; src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; } else { env = GL_REPLACE; src = GL_SRC_ALPHA; } const GGLfixed alpha = (s.alpha << 16)/255; glColor4x(alpha, alpha, alpha, alpha); glEnable(GL_BLEND); glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, env); } else { glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glColor4x(0x10000, 0x10000, 0x10000, 0x10000); if (needsBlending()) { GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; glEnable(GL_BLEND); glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); } else { glDisable(GL_BLEND); } } if (UNLIKELY(transformed() || !(mFlags & DisplayHardware::DRAW_TEXTURE_EXTENSION) )) { //StopWatch watch("GL transformed"); Region::iterator iterator(clip); if (iterator) { // always use high-quality filtering with fast configurations bool fast = !(mFlags & DisplayHardware::SLOW_CONFIG); if (!fast && s.flags & ISurfaceComposer::eLayerFilter) { glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } const GLfixed texCoords[4][2] = { { 0, 0 }, { 0, 0x10000 }, { 0x10000, 0x10000 }, { 0x10000, 0 } }; glMatrixMode(GL_TEXTURE); glLoadIdentity(); if (!(mFlags & DisplayHardware::NPOT_EXTENSION)) { // find the smallest power-of-two that will accommodate our surface GLuint tw = 1 << (31 - clz(t.width)); GLuint th = 1 << (31 - clz(t.height)); if (tw < t.width) tw <<= 1; if (th < t.height) th <<= 1; // this divide should be relatively fast because it's // a power-of-two (optimized path in libgcc) GLfloat ws = GLfloat(t.width) /tw; GLfloat hs = GLfloat(t.height)/th; glScalef(ws, hs, 1.0f); } glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(2, GL_FIXED, 0, mVertices); glTexCoordPointer(2, GL_FIXED, 0, texCoords); Rect r; while (iterator.iterate(&r)) { const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } if (!fast && s.flags & ISurfaceComposer::eLayerFilter) { glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } glDisableClientState(GL_TEXTURE_COORD_ARRAY); } } else { Region::iterator iterator(clip); if (iterator) { Rect r; GLint crop[4] = { 0, t.height, t.width, -t.height }; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop); int x = tx(); int y = ty(); y = fbHeight - (y + t.height); while (iterator.iterate(&r)) { const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); glDrawTexiOES(x, y, 0, t.width, t.height); } } } }
void LayerBase::drawWithOpenGL(const Region& clip) const { const DisplayHardware& hw(graphicPlane(0).displayHardware()); const uint32_t fbHeight = hw.getHeight(); const State& s(drawingState()); GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; if (CC_UNLIKELY(s.alpha < 0xFF)) { const GLfloat alpha = s.alpha * (1.0f/255.0f); if (mPremultipliedAlpha) { glColor4f(alpha, alpha, alpha, alpha); } else { glColor4f(1, 1, 1, alpha); } glEnable(GL_BLEND); glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } else { glColor4f(1, 1, 1, 1); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); if (!isOpaque()) { glEnable(GL_BLEND); glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); } else { glDisable(GL_BLEND); } } struct TexCoords { GLfloat u; GLfloat v; }; Rect crop(s.active.w, s.active.h); if (!s.active.crop.isEmpty()) { crop = s.active.crop; } GLfloat left = GLfloat(crop.left) / GLfloat(s.active.w); GLfloat top = GLfloat(crop.top) / GLfloat(s.active.h); GLfloat right = GLfloat(crop.right) / GLfloat(s.active.w); GLfloat bottom = GLfloat(crop.bottom) / GLfloat(s.active.h); TexCoords texCoords[4]; texCoords[0].u = left; texCoords[0].v = top; texCoords[1].u = left; texCoords[1].v = bottom; texCoords[2].u = right; texCoords[2].v = bottom; texCoords[3].u = right; texCoords[3].v = top; for (int i = 0; i < 4; i++) { texCoords[i].v = 1.0f - texCoords[i].v; } glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(2, GL_FLOAT, 0, mVertices); glTexCoordPointer(2, GL_FLOAT, 0, texCoords); glDrawArrays(GL_TRIANGLE_FAN, 0, mNumVertices); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisable(GL_BLEND); }
void Layer::lockPageFlip(bool& recomputeVisibleRegions) { if (mQueuedFrames > 0) { // Capture the old state of the layer for comparisons later const bool oldOpacity = isOpaque(); sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer; // signal another event if we have more frames pending if (android_atomic_dec(&mQueuedFrames) > 1) { mFlinger->signalEvent(); } const DisplayHardware& hw(graphicPlane(0).displayHardware()); bool avoidTex = (hw.getFlags() & DisplayHardware::MDP_COMPOSITION) ? true : false; if (mSurfaceTexture->updateTexImage(avoidTex) < NO_ERROR) { // something happened! recomputeVisibleRegions = true; return; } updateLayerQcomFlags(LAYER_UPDATE_STATUS, true, mLayerQcomFlags); // update the active buffer mActiveBuffer = mSurfaceTexture->getCurrentBuffer(); const Rect crop(mSurfaceTexture->getCurrentCrop()); const uint32_t transform(mSurfaceTexture->getCurrentTransform()); const uint32_t scalingMode(mSurfaceTexture->getCurrentScalingMode()); if ((crop != mCurrentCrop) || (transform != mCurrentTransform) || (scalingMode != mCurrentScalingMode)) { mCurrentCrop = crop; mCurrentTransform = transform; mCurrentScalingMode = scalingMode; mFlinger->invalidateHwcGeometry(); } GLfloat textureMatrix[16]; mSurfaceTexture->getTransformMatrix(textureMatrix); if (memcmp(textureMatrix, mTextureMatrix, sizeof(textureMatrix))) { memcpy(mTextureMatrix, textureMatrix, sizeof(textureMatrix)); mFlinger->invalidateHwcGeometry(); } uint32_t bufWidth = mActiveBuffer->getWidth(); uint32_t bufHeight = mActiveBuffer->getHeight(); if (oldActiveBuffer != NULL) { if (bufWidth != uint32_t(oldActiveBuffer->width) || bufHeight != uint32_t(oldActiveBuffer->height)) { mFlinger->invalidateHwcGeometry(); } } mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format); if (oldOpacity != isOpaque()) { recomputeVisibleRegions = true; } glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // update the layer size if needed const Layer::State& front(drawingState()); // FIXME: mPostedDirtyRegion = dirty & bounds mPostedDirtyRegion.set(front.w, front.h); if ((front.w != front.requested_w) || (front.h != front.requested_h)) { // check that we received a buffer of the right size // (Take the buffer's orientation into account) if (mCurrentTransform & Transform::ROT_90) { swap(bufWidth, bufHeight); } if (isFixedSize() || (bufWidth == front.requested_w && bufHeight == front.requested_h)) { // Here we pretend the transaction happened by updating the // current and drawing states. Drawing state is only accessed // in this thread, no need to have it locked Layer::State& editDraw(mDrawingState); editDraw.w = editDraw.requested_w; editDraw.h = editDraw.requested_h; // We also need to update the current state so that we don't // end-up doing too much work during the next transaction. // NOTE: We actually don't need hold the transaction lock here // because State::w and State::h are only accessed from // this thread Layer::State& editTemp(currentState()); editTemp.w = editDraw.w; editTemp.h = editDraw.h; // recompute visible region recomputeVisibleRegions = true; } LOGD_IF(DEBUG_RESIZE, "lockPageFlip : " " (layer=%p), buffer (%ux%u, tr=%02x), " "requested (%dx%d)", this, bufWidth, bufHeight, mCurrentTransform, front.requested_w, front.requested_h); } } else { updateLayerQcomFlags(LAYER_UPDATE_STATUS, false, mLayerQcomFlags); } }
status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f, uint32_t sw, uint32_t sh) { LOGI("captureScreenImplLocked"); status_t result = PERMISSION_DENIED; // only one display supported for now if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) return BAD_VALUE; if (!GLExtensions::getInstance().haveFramebufferObject()) return INVALID_OPERATION; // get screen geometry const DisplayHardware& hw(graphicPlane(dpy).displayHardware()); const uint32_t hw_w = hw.getWidth(); const uint32_t hw_h = hw.getHeight(); if ((sw > hw_w) || (sh > hw_h)) return BAD_VALUE; sw = (!sw) ? hw_w : sw; sh = (!sh) ? hw_h : sh; const size_t size = sw * sh * 4; // make sure to clear all GL error flags while ( glGetError() != GL_NO_ERROR ) ; // create a FBO GLuint name, tname; glGenRenderbuffersOES(1, &tname); glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname); glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh); glGenFramebuffersOES(1, &name); glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname); GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); if (status == GL_FRAMEBUFFER_COMPLETE_OES) { // invert everything, b/c glReadPixel() below will invert the FB glViewport(0, 0, sw, sh); glScissor(0, 0, sw, sh); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrthof(0, hw_w, 0, hw_h, 0, 1); glMatrixMode(GL_MODELVIEW); // redraw the screen entirely... glClearColor(0,0,0,1); glClear(GL_COLOR_BUFFER_BIT); const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); const size_t count = layers.size(); for (size_t i=0 ; i<count ; ++i) { const sp<LayerBase>& layer(layers[i]); layer->drawForSreenShot(); } // XXX: this is needed on tegra glScissor(0, 0, sw, sh); // check for errors and return screen capture if (glGetError() != GL_NO_ERROR) { // error while rendering result = INVALID_OPERATION; } else { // allocate shared memory large enough to hold the // screen capture sp<MemoryHeapBase> base( new MemoryHeapBase(size, 0, "screen-capture") ); void* const ptr = base->getBase(); if (ptr) { // capture the screen with glReadPixels() glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr); if (glGetError() == GL_NO_ERROR) { *heap = base; *w = sw; *h = sh; *f = PIXEL_FORMAT_RGBA_8888; result = NO_ERROR; } } else { result = NO_MEMORY; } } glEnable(GL_SCISSOR_TEST); glViewport(0, 0, hw_w, hw_h); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); } else { result = BAD_VALUE; } // release FBO resources glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); glDeleteRenderbuffersOES(1, &tname); glDeleteFramebuffersOES(1, &name); hw.compositionComplete(); return result; }
//end void LayerBase::drawWithOpenGL(const Region& clip) const { const DisplayHardware& hw(graphicPlane(0).displayHardware()); const uint32_t fbHeight = hw.getHeight(); const uint32_t fbWidth = hw.getWidth(); const State& s(drawingState()); const SurfaceFlinger::State& sSF = mFlinger->getDrawingState(); GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; if (UNLIKELY(s.alpha < 0xFF)) { const GLfloat alpha = s.alpha * (1.0f/255.0f); if (mPremultipliedAlpha) { glColor4f(alpha, alpha, alpha, alpha); } else { glColor4f(1, 1, 1, alpha); } glEnable(GL_BLEND); glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } else { glColor4f(1, 1, 1, 1); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); if (!isOpaque()) { glEnable(GL_BLEND); glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); } else { glDisable(GL_BLEND); } } //first judge wheather is 3D module 40641 const uint32_t hw_w_half = hw.getWidth()/2; struct TexCoords { GLfloat u; GLfloat v; }; TexCoords texCoords[4]; //judge if 3D modle switch(sSF.composing3D){ case eSTEREO_OSD_3D_NONE: { drawNormal(clip,fbHeight,mDrawingState.flags); break; } case eSTEREO_OSD_3D_SBSHALFE_PR: { drawSideBySide(clip,hw_w_half,fbHeight,mDrawingState.flags); break; } case eSTEREO_OSD_3D_TPANDBT_PR: { drawTopAndBottom(clip,fbHeight,mDrawingState.flags); break; } default: break; } glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisable(GL_BLEND); }
void Layer::setGeometry(hwc_layer_t* hwcl) { LayerBaseClient::setGeometry(hwcl); hwcl->flags &= ~HWC_SKIP_LAYER; const DisplayHardware& hw(graphicPlane(0).displayHardware()); // we can't do alpha-fade with the hwc HAL, // unless we are using C2D const State& s(drawingState()); if (s.alpha < 0xFF) { if ((QCCompositionType::getInstance().getCompositionType() & COMPOSITION_TYPE_C2D) && (!isOpaque())) { hwcl->blending = mPremultipliedAlpha ? HWC_BLENDING_PREMULT : HWC_BLENDING_COVERAGE; } else { hwcl->flags = HWC_SKIP_LAYER; } } //hwcl->alpha = s.alpha; /* * Transformations are applied in this order: * 1) buffer orientation/flip/mirror * 2) state transformation (window manager) * 3) layer orientation (screen orientation) * mTransform is already the composition of (2) and (3) * (NOTE: the matrices are multiplied in reverse order) */ const Transform bufferOrientation(mCurrentTransform); const Transform tr(mTransform * bufferOrientation); // this gives us only the "orientation" component of the transform const uint32_t finalTransform = tr.getOrientation(); // we can only handle simple transformation if (finalTransform & Transform::ROT_INVALID) { hwcl->flags = HWC_SKIP_LAYER; } else { hwcl->transform = finalTransform; //mBufferTransform will have the srcTransform //include src and final transform in the hwcl->transform hwcl->transform = (( bufferOrientation.getOrientation() << SHIFT_SRC_TRANSFORM) | hwcl->transform); } if (isCropped()) { hwcl->sourceCrop.left = mCurrentCrop.left; hwcl->sourceCrop.top = mCurrentCrop.top; hwcl->sourceCrop.right = mCurrentCrop.right; hwcl->sourceCrop.bottom = mCurrentCrop.bottom; } else { const sp<GraphicBuffer>& buffer(mActiveBuffer); hwcl->sourceCrop.left = 0; hwcl->sourceCrop.top = 0; if (buffer != NULL) { hwcl->sourceCrop.right = buffer->width; hwcl->sourceCrop.bottom = buffer->height; } else { hwcl->sourceCrop.right = mTransformedBounds.width(); hwcl->sourceCrop.bottom = mTransformedBounds.height(); } } }