Created HardwareBufferRenderer to support rendering into
HardwareBuffer targets.

Relnote: "Created HardwareBufferRenderer API to handle
rendering a single frame into a HardwareBuffer target."

Refactored dlsym logic for dynamically resolving AHardwareBuffer
methods to be shared across multiple locations.

Bug: 255692581
Test: Created HardwareBufferRendererTests
Change-Id: I749b5d763a9ee580abc2d6cc87bd94a46b7abdd9
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 78ae5cf..b769f8d 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -153,6 +153,7 @@
 
 void CanvasContext::destroy() {
     stopDrawing();
+    setHardwareBuffer(nullptr);
     setSurface(nullptr);
     setSurfaceControl(nullptr);
     freePrefetchedLayers();
@@ -176,6 +177,19 @@
     native_window_set_buffer_count(window, bufferCount);
 }
 
+void CanvasContext::setHardwareBuffer(AHardwareBuffer* buffer) {
+    if (mHardwareBuffer) {
+        AHardwareBuffer_release(mHardwareBuffer);
+        mHardwareBuffer = nullptr;
+    }
+
+    if (buffer) {
+        AHardwareBuffer_acquire(buffer);
+        mHardwareBuffer = buffer;
+    }
+    mRenderPipeline->setHardwareBuffer(mHardwareBuffer);
+}
+
 void CanvasContext::setSurface(ANativeWindow* window, bool enableTimeout) {
     ATRACE_CALL();
 
@@ -257,7 +271,7 @@
             mRenderThread.removeFrameCallback(this);
             mRenderPipeline->onStop();
             mRenderThread.cacheManager().onContextStopped(this);
-        } else if (mIsDirty && hasSurface()) {
+        } else if (mIsDirty && hasOutputTarget()) {
             mRenderThread.postFrameCallback(this);
         }
     }
@@ -390,7 +404,7 @@
 
     mIsDirty = true;
 
-    if (CC_UNLIKELY(!hasSurface())) {
+    if (CC_UNLIKELY(!hasOutputTarget())) {
         mCurrentFrameInfo->addFlag(FrameInfoFlags::SkippedFrame);
         info.out.canDrawThisFrame = false;
         return;
@@ -535,7 +549,7 @@
         std::scoped_lock lock(mFrameMetricsReporterMutex);
         drawResult = mRenderPipeline->draw(frame, windowDirty, dirty, mLightGeometry,
                                            &mLayerUpdateQueue, mContentDrawBounds, mOpaque,
-                                           mLightInfo, mRenderNodes, &(profiler()));
+                                           mLightInfo, mRenderNodes, &(profiler()), mBufferParams);
     }
 
     uint64_t frameCompleteNr = getFrameNumber();