nsRegion nsFilterInstance::FilterSpaceToFrameSpace(const nsIntRegion& aRegion) const { nsRegion result; for (auto iter = aRegion.RectIter(); !iter.Done(); iter.Next()) { // FilterSpaceToFrameSpace rounds out, so this works. result.Or(result, FilterSpaceToFrameSpace(iter.Get())); } return result; }
void AppendToString(std::stringstream& aStream, const nsIntRegion& r, const char* pfx, const char* sfx) { aStream << pfx; aStream << "< "; for (auto iter = r.RectIter(); !iter.Done(); iter.Next()) { AppendToString(aStream, iter.Get()); aStream << "; "; } aStream << ">"; aStream << sfx; }
/* static */ bool HwcUtils::PrepareVisibleRegion(const nsIntRegion& aVisible, const gfx::Matrix& aLayerTransform, const gfx::Matrix& aLayerBufferTransform, nsIntRect aClip, nsIntRect aBufferRect, RectVector* aVisibleRegionScreen, bool& aIsVisible) { const float MIN_SRC_WIDTH = 2.f; const float MIN_SRC_HEIGHT = 2.f; gfxMatrix layerTransform = gfx::ThebesMatrix(aLayerTransform); gfxMatrix layerBufferTransform = gfx::ThebesMatrix(aLayerBufferTransform); gfxRect bufferRect = layerBufferTransform.TransformBounds(ThebesRect(aBufferRect)); gfxMatrix inverse = gfx::ThebesMatrix(aLayerBufferTransform); inverse.Invert(); aIsVisible = false; for (auto iter = aVisible.RectIter(); !iter.Done(); iter.Next()) { gfxRect screenRect = layerTransform.TransformBounds(ThebesRect(iter.Get())); screenRect.IntersectRect(screenRect, bufferRect); screenRect.IntersectRect(screenRect, ThebesRect(aClip)); screenRect.Round(); if (screenRect.IsEmpty()) { continue; } hwc_rect_t visibleRectScreen; visibleRectScreen.left = screenRect.x; visibleRectScreen.top = screenRect.y; visibleRectScreen.right = screenRect.XMost(); visibleRectScreen.bottom = screenRect.YMost(); gfxRect srcCrop = inverse.TransformBounds(screenRect); // When src crop is very small, HWC could not render correctly in some cases. // See Bug 1169093 if(srcCrop.Width() < MIN_SRC_WIDTH || srcCrop.Height() < MIN_SRC_HEIGHT) { return false; } aVisibleRegionScreen->push_back(visibleRectScreen); aIsVisible = true; } return true; }
void Compositor::DrawDiagnostics(DiagnosticFlags aFlags, const nsIntRegion& aVisibleRegion, const gfx::IntRect& aClipRect, const gfx::Matrix4x4& aTransform, uint32_t aFlashCounter) { if (!ShouldDrawDiagnostics(aFlags)) { return; } if (aVisibleRegion.GetNumRects() > 1) { for (auto iter = aVisibleRegion.RectIter(); !iter.Done(); iter.Next()) { DrawDiagnostics(aFlags | DiagnosticFlags::REGION_RECT, IntRectToRect(iter.Get()), aClipRect, aTransform, aFlashCounter); } } DrawDiagnostics(aFlags, IntRectToRect(aVisibleRegion.GetBounds()), aClipRect, aTransform, aFlashCounter); }
SurfaceFormat UploadImageDataToTexture(GLContext* gl, unsigned char* aData, int32_t aStride, SurfaceFormat aFormat, const nsIntRegion& aDstRegion, GLuint aTexture, const gfx::IntSize& aSize, size_t* aOutUploadSize, bool aNeedInit, GLenum aTextureUnit, GLenum aTextureTarget) { gl->MakeCurrent(); gl->fActiveTexture(aTextureUnit); gl->fBindTexture(aTextureTarget, aTexture); GLenum format = 0; GLenum internalFormat = 0; GLenum type = 0; int32_t pixelSize = BytesPerPixel(aFormat); SurfaceFormat surfaceFormat = gfx::SurfaceFormat::UNKNOWN; MOZ_ASSERT(gl->GetPreferredARGB32Format() == LOCAL_GL_BGRA || gl->GetPreferredARGB32Format() == LOCAL_GL_RGBA); switch (aFormat) { case SurfaceFormat::B8G8R8A8: if (gl->GetPreferredARGB32Format() == LOCAL_GL_BGRA) { format = LOCAL_GL_BGRA; surfaceFormat = SurfaceFormat::R8G8B8A8; type = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV; } else { format = LOCAL_GL_RGBA; surfaceFormat = SurfaceFormat::B8G8R8A8; type = LOCAL_GL_UNSIGNED_BYTE; } internalFormat = LOCAL_GL_RGBA; break; case SurfaceFormat::B8G8R8X8: // Treat BGRX surfaces as BGRA except for the surface // format used. if (gl->GetPreferredARGB32Format() == LOCAL_GL_BGRA) { format = LOCAL_GL_BGRA; surfaceFormat = SurfaceFormat::R8G8B8X8; type = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV; } else { format = LOCAL_GL_RGBA; surfaceFormat = SurfaceFormat::B8G8R8X8; type = LOCAL_GL_UNSIGNED_BYTE; } internalFormat = LOCAL_GL_RGBA; break; case SurfaceFormat::R8G8B8A8: if (gl->GetPreferredARGB32Format() == LOCAL_GL_BGRA) { // Upload our RGBA as BGRA, but store that the uploaded format is // BGRA. (sample from R to get B) format = LOCAL_GL_BGRA; type = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV; surfaceFormat = SurfaceFormat::B8G8R8A8; } else { format = LOCAL_GL_RGBA; type = LOCAL_GL_UNSIGNED_BYTE; surfaceFormat = SurfaceFormat::R8G8B8A8; } internalFormat = LOCAL_GL_RGBA; break; case SurfaceFormat::R8G8B8X8: // Treat RGBX surfaces as RGBA except for the surface // format used. if (gl->GetPreferredARGB32Format() == LOCAL_GL_BGRA) { format = LOCAL_GL_BGRA; type = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV; surfaceFormat = SurfaceFormat::B8G8R8X8; } else { format = LOCAL_GL_RGBA; type = LOCAL_GL_UNSIGNED_BYTE; surfaceFormat = SurfaceFormat::R8G8B8X8; } internalFormat = LOCAL_GL_RGBA; break; case SurfaceFormat::R5G6B5_UINT16: internalFormat = format = LOCAL_GL_RGB; type = LOCAL_GL_UNSIGNED_SHORT_5_6_5; surfaceFormat = SurfaceFormat::R5G6B5_UINT16; break; case SurfaceFormat::A8: internalFormat = format = LOCAL_GL_LUMINANCE; type = LOCAL_GL_UNSIGNED_BYTE; // We don't have a specific luminance shader surfaceFormat = SurfaceFormat::A8; break; default: NS_ASSERTION(false, "Unhandled image surface format!"); } if (aOutUploadSize) { *aOutUploadSize = 0; } if (aNeedInit || !CanUploadSubTextures(gl)) { // If the texture needs initialized, or we are unable to // upload sub textures, then initialize and upload the entire // texture. TexImage2DHelper(gl, aTextureTarget, 0, internalFormat, aSize.width, aSize.height, aStride, pixelSize, 0, format, type, aData); if (aOutUploadSize && aNeedInit) { uint32_t texelSize = GetBytesPerTexel(internalFormat, type); size_t numTexels = size_t(aSize.width) * size_t(aSize.height); *aOutUploadSize += texelSize * numTexels; } } else { // Upload each rect in the region to the texture for (auto iter = aDstRegion.RectIter(); !iter.Done(); iter.Next()) { const IntRect& rect = iter.Get(); const unsigned char* rectData = aData + DataOffset(rect.TopLeft(), aStride, aFormat); TexSubImage2DHelper(gl, aTextureTarget, 0, rect.x, rect.y, rect.Width(), rect.Height(), aStride, pixelSize, format, type, rectData); } } return surfaceFormat; }