drm_hwcomposer: move AddFb/RmFb to reference gem handles

Move drmModeAddFB2 and drmModeRmFB to ensure a reference to the gem
handles are taken while the buffer is in use.

Change-Id: Ib9afdb91144850480ecaac9d73601d887af5fa12
Reviewed-on: https://chrome-internal-review.googlesource.com/200686
Reviewed-by: Stéphane Marchesin <marcheu@google.com>
Commit-Queue: Stéphane Marchesin <marcheu@google.com>
Tested-by: Stéphane Marchesin <marcheu@google.com>
diff --git a/hwcomposer.cpp b/hwcomposer.cpp
index 77caf90..12b3e04 100644
--- a/hwcomposer.cpp
+++ b/hwcomposer.cpp
@@ -290,28 +290,12 @@
 		}
 	}
 
-	ret = drmModeAddFB2(hd->ctx->fd, buf->width,
-		buf->height, buf->format, buf->gem_handles, buf->pitches,
-		buf->offsets, &buf->fb_id, 0);
-	if (ret) {
-		ALOGE("could not create drm fb %d", ret);
-		return ret;
-	}
-
 	ret = hwc_flip(hd, buf);
 	if (ret) {
 		ALOGE("Failed to perform flip\n");
 		return ret;
 	}
 
-	if (hd->front.fb_id) {
-		ret = drmModeRmFB(hd->ctx->fd, hd->front.fb_id);
-		if (ret) {
-			ALOGE("Failed to rm fb from front %d", ret);
-			return ret;
-		}
-	}
-
 	memset(&args, 0, sizeof(args));
 	for (i = 0; i < ARRAY_SIZE(hd->front.gem_handles); i++) {
 		if (!hd->front.gem_handles[i])
@@ -345,6 +329,15 @@
 		if (pthread_mutex_unlock(&hd->set_worker.lock))
 			ALOGE("Failed to unlock set lock in wait_and_set() %d", ret);
 	}
+
+	if (hd->front.fb_id) {
+		ret = drmModeRmFB(hd->ctx->fd, hd->front.fb_id);
+		if (ret) {
+			ALOGE("Failed to rm fb from front %d", ret);
+			return ret;
+		}
+	}
+
 	hd->front = *buf;
 
 	return ret;
@@ -461,6 +454,14 @@
 	buf.acquire_fence_fd = layer->acquireFenceFd;
 	layer->acquireFenceFd = -1;
 
+	ret = drmModeAddFB2(hd->ctx->fd, buf.width,
+		buf.height, buf.format, buf.gem_handles, buf.pitches,
+		buf.offsets, &buf.fb_id, 0);
+	if (ret) {
+		ALOGE("could not create drm fb %d", ret);
+		goto out;
+	}
+
 	/*
 	 * TODO: Retire and release can use the same sync point here b/c hwc is
 	 * restricted to one layer. Once that is no longer true, this will need