michael@0: /* michael@0: * Copyright (c) 2013 The Linux Foundation. All rights reserved. michael@0: * michael@0: * Licensed under the Apache License, Version 2.0 (the "License"); michael@0: * you may not use this file except in compliance with the License. michael@0: * You may obtain a copy of the License at michael@0: * michael@0: * http://www.apache.org/licenses/LICENSE-2.0 michael@0: * michael@0: * Unless required by applicable law or agreed to in writing, software michael@0: * distributed under the License is distributed on an "AS IS" BASIS, michael@0: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. michael@0: * See the License for the specific language governing permissions and michael@0: * limitations under the License. michael@0: */ michael@0: michael@0: #include michael@0: #include "HwcUtils.h" michael@0: #include "gfxUtils.h" michael@0: michael@0: #define LOG_TAG "HwcUtils" michael@0: michael@0: #if (LOG_NDEBUG == 0) michael@0: #define LOGD(args...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, ## args) michael@0: #else michael@0: #define LOGD(args...) ((void)0) michael@0: #endif michael@0: michael@0: #define LOGE(args...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, ## args) michael@0: michael@0: michael@0: namespace mozilla { michael@0: michael@0: /* Utility functions for HwcComposer */ michael@0: michael@0: michael@0: michael@0: /* static */ bool michael@0: HwcUtils::PrepareLayerRects(nsIntRect aVisible, const gfxMatrix& aTransform, michael@0: nsIntRect aClip, nsIntRect aBufferRect, michael@0: bool aYFlipped, michael@0: hwc_rect_t* aSourceCrop, hwc_rect_t* aVisibleRegionScreen) { michael@0: michael@0: gfxRect visibleRect(aVisible); michael@0: gfxRect clip(aClip); michael@0: gfxRect visibleRectScreen = aTransform.TransformBounds(visibleRect); michael@0: // |clip| is guaranteed to be integer michael@0: visibleRectScreen.IntersectRect(visibleRectScreen, clip); michael@0: michael@0: if (visibleRectScreen.IsEmpty()) { michael@0: LOGD("Skip layer"); michael@0: return false; michael@0: } michael@0: michael@0: gfxMatrix inverse(aTransform); michael@0: inverse.Invert(); michael@0: gfxRect crop = inverse.TransformBounds(visibleRectScreen); michael@0: michael@0: //clip to buffer size michael@0: crop.IntersectRect(crop, aBufferRect); michael@0: crop.Round(); michael@0: michael@0: if (crop.IsEmpty()) { michael@0: LOGD("Skip layer"); michael@0: return false; michael@0: } michael@0: michael@0: //propagate buffer clipping back to visible rect michael@0: visibleRectScreen = aTransform.TransformBounds(crop); michael@0: visibleRectScreen.Round(); michael@0: michael@0: // Map from layer space to buffer space michael@0: crop -= aBufferRect.TopLeft(); michael@0: if (aYFlipped) { michael@0: crop.y = aBufferRect.height - (crop.y + crop.height); michael@0: } michael@0: michael@0: aSourceCrop->left = crop.x; michael@0: aSourceCrop->top = crop.y; michael@0: aSourceCrop->right = crop.x + crop.width; michael@0: aSourceCrop->bottom = crop.y + crop.height; michael@0: michael@0: aVisibleRegionScreen->left = visibleRectScreen.x; michael@0: aVisibleRegionScreen->top = visibleRectScreen.y; michael@0: aVisibleRegionScreen->right = visibleRectScreen.x + visibleRectScreen.width; michael@0: aVisibleRegionScreen->bottom = visibleRectScreen.y + visibleRectScreen.height; michael@0: michael@0: return true; michael@0: } michael@0: michael@0: /* static */ bool michael@0: HwcUtils::PrepareVisibleRegion(const nsIntRegion& aVisible, michael@0: const gfxMatrix& aTransform, michael@0: nsIntRect aClip, nsIntRect aBufferRect, michael@0: RectVector* aVisibleRegionScreen) { michael@0: michael@0: nsIntRegionRectIterator rect(aVisible); michael@0: bool isVisible = false; michael@0: while (const nsIntRect* visibleRect = rect.Next()) { michael@0: hwc_rect_t visibleRectScreen; michael@0: gfxRect screenRect; michael@0: michael@0: screenRect.IntersectRect(gfxRect(*visibleRect), aBufferRect); michael@0: screenRect = aTransform.TransformBounds(screenRect); michael@0: screenRect.IntersectRect(screenRect, aClip); michael@0: screenRect.Round(); michael@0: if (screenRect.IsEmpty()) { michael@0: continue; michael@0: } michael@0: visibleRectScreen.left = screenRect.x; michael@0: visibleRectScreen.top = screenRect.y; michael@0: visibleRectScreen.right = screenRect.XMost(); michael@0: visibleRectScreen.bottom = screenRect.YMost(); michael@0: aVisibleRegionScreen->push_back(visibleRectScreen); michael@0: isVisible = true; michael@0: } michael@0: michael@0: return isVisible; michael@0: } michael@0: michael@0: /* static */ bool michael@0: HwcUtils::CalculateClipRect(const gfxMatrix& aTransform, michael@0: const nsIntRect* aLayerClip, michael@0: nsIntRect aParentClip, nsIntRect* aRenderClip) { michael@0: michael@0: *aRenderClip = aParentClip; michael@0: michael@0: if (!aLayerClip) { michael@0: return true; michael@0: } michael@0: michael@0: if (aLayerClip->IsEmpty()) { michael@0: return false; michael@0: } michael@0: michael@0: nsIntRect clip = *aLayerClip; michael@0: michael@0: gfxRect r(clip); michael@0: gfxRect trClip = aTransform.TransformBounds(r); michael@0: trClip.Round(); michael@0: gfxUtils::GfxRectToIntRect(trClip, &clip); michael@0: michael@0: aRenderClip->IntersectRect(*aRenderClip, clip); michael@0: return true; michael@0: } michael@0: michael@0: } // namespace mozilla