Don't create layers for negative-sized RenderNodes

Fixes: 257954570
Test: n/a
Flag: EXEMPT trivial bug fix
Change-Id: I82a00ec21b58ea55779d02db4a54d1ef2d37dcc7
diff --git a/libs/hwui/DeviceInfo.h b/libs/hwui/DeviceInfo.h
index fb58a69..b72e066 100644
--- a/libs/hwui/DeviceInfo.h
+++ b/libs/hwui/DeviceInfo.h
@@ -84,6 +84,7 @@
     // this value is only valid after the GPU has been initialized and there is a valid graphics
     // context or if you are using the HWUI_NULL_GPU
     int maxTextureSize() const;
+    bool hasMaxTextureSize() const { return mMaxTextureSize > 0; }
     sk_sp<SkColorSpace> getWideColorSpace() const { return mWideColorSpace; }
     SkColorType getWideColorType() {
         static std::once_flag kFlag;
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 2c23864..4801bd1 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -186,7 +186,7 @@
     // If we are not a layer OR we cannot be rendered (eg, view was detached)
     // we need to destroy any Layers we may have had previously
     if (CC_LIKELY(layerType != LayerType::RenderLayer) || CC_UNLIKELY(!isRenderable()) ||
-        CC_UNLIKELY(properties().getWidth() == 0) || CC_UNLIKELY(properties().getHeight() == 0) ||
+        CC_UNLIKELY(properties().getWidth() <= 0) || CC_UNLIKELY(properties().getHeight() <= 0) ||
         CC_UNLIKELY(!properties().fitsOnLayer())) {
         if (CC_UNLIKELY(hasLayer())) {
             this->setLayerSurface(nullptr);
diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h
index b1ad8b2..4dc5700 100644
--- a/libs/hwui/RenderProperties.h
+++ b/libs/hwui/RenderProperties.h
@@ -545,7 +545,8 @@
     bool fitsOnLayer() const {
         const DeviceInfo* deviceInfo = DeviceInfo::get();
         return mPrimitiveFields.mWidth <= deviceInfo->maxTextureSize() &&
-               mPrimitiveFields.mHeight <= deviceInfo->maxTextureSize();
+               mPrimitiveFields.mHeight <= deviceInfo->maxTextureSize() &&
+               mPrimitiveFields.mWidth > 0 && mPrimitiveFields.mHeight > 0;
     }
 
     bool promotedToLayer() const {
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 8ec0430..b36b8be 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -418,6 +418,11 @@
                                 RenderNode* target) {
     mRenderThread.removeFrameCallback(this);
 
+    // Make sure we have a valid device info
+    if (!DeviceInfo::get()->hasMaxTextureSize()) {
+        (void)mRenderThread.requireGrContext();
+    }
+
     // If the previous frame was dropped we don't need to hold onto it, so
     // just keep using the previous frame's structure instead
     const auto reason = wasSkipped(mCurrentFrameInfo);
diff --git a/libs/hwui/tests/unit/RenderPropertiesTests.cpp b/libs/hwui/tests/unit/RenderPropertiesTests.cpp
index 3e8e057..6ec042c 100644
--- a/libs/hwui/tests/unit/RenderPropertiesTests.cpp
+++ b/libs/hwui/tests/unit/RenderPropertiesTests.cpp
@@ -40,7 +40,11 @@
     props.setLeftTopRightBottom(0, 0, maxTextureSize + 1, maxTextureSize + 1);
     ASSERT_FALSE(props.fitsOnLayer());
 
-    // Too small, but still 'fits'. Not fitting is an error case, so don't report empty as such.
+    // Too small, we can't create a layer for a 0 width or height
     props.setLeftTopRightBottom(0, 0, 100, 0);
-    ASSERT_TRUE(props.fitsOnLayer());
+    ASSERT_FALSE(props.fitsOnLayer());
+
+    // Can't create a negative-sized layer
+    props.setLeftTopRightBottom(0, 0, -100, 300);
+    ASSERT_FALSE(props.fitsOnLayer());
 }