Change type of |upload_pixels_| to improve performance

For issue 817341, fuzzer tests were taking a long time due to calls to
std::vector<uint8_t>::resize(), as it initializes each element one by
one. Switching to std::unique_ptr<uint8_t[]> speed things up, as the
elements are not initialized. As VideoResourceUpdater allocates a
temporary buffer to hold a video frame, it could also benefit from the
improved execution time.

BUG=817341
TEST=media_unittests pass

Change-Id: I63c1afce3eb6b654c8863a555642ee3e05c1c883
Reviewed-on: https://chromium-review.googlesource.com/1137063
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
Commit-Queue: John Rummell <jrummell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#575479}
diff --git a/media/renderers/video_resource_updater.cc b/media/renderers/video_resource_updater.cc
index efb9234..952c9a7 100644
--- a/media/renderers/video_resource_updater.cc
+++ b/media/renderers/video_resource_updater.cc
@@ -872,14 +872,16 @@
         size_t bytes_per_row = viz::ResourceSizes::CheckedWidthInBytes<size_t>(
             video_frame->coded_size().width(), viz::ResourceFormat::RGBA_8888);
         size_t needed_size = bytes_per_row * video_frame->coded_size().height();
-        if (upload_pixels_.size() < needed_size) {
-          // Clear before resizing to avoid memcpy.
-          upload_pixels_.clear();
-          upload_pixels_.resize(needed_size);
+        if (upload_pixels_size_ < needed_size) {
+          // Free the existing data first so that the memory can be reused,
+          // if possible. Note that the new array is purposely not initialized.
+          upload_pixels_.reset();
+          upload_pixels_.reset(new uint8_t[needed_size]);
+          upload_pixels_size_ = needed_size;
         }
 
         PaintCanvasVideoRenderer::ConvertVideoFrameToRGBPixels(
-            video_frame.get(), &upload_pixels_[0], bytes_per_row);
+            video_frame.get(), upload_pixels_.get(), bytes_per_row);
 
         // Copy pixels into texture.
         auto* gl = context_provider_->ContextGL();
@@ -889,7 +891,7 @@
         gl->TexSubImage2D(
             hardware_resource->texture_target(), 0, 0, 0, plane_size.width(),
             plane_size.height(), GLDataFormat(viz::ResourceFormat::RGBA_8888),
-            GLDataType(viz::ResourceFormat::RGBA_8888), &upload_pixels_[0]);
+            GLDataType(viz::ResourceFormat::RGBA_8888), upload_pixels_.get());
       }
       plane_resource->SetUniqueId(video_frame->unique_id(), 0);
     }
@@ -997,10 +999,12 @@
       // Avoid malloc for each frame/plane if possible.
       const size_t needed_size =
           upload_image_stride * resource_size_pixels.height();
-      if (upload_pixels_.size() < needed_size) {
-        // Clear before resizing to avoid memcpy.
-        upload_pixels_.clear();
-        upload_pixels_.resize(needed_size);
+      if (upload_pixels_size_ < needed_size) {
+        // Free the existing data first so that the memory can be reused,
+        // if possible. Note that the new array is purposely not initialized.
+        upload_pixels_.reset();
+        upload_pixels_.reset(new uint8_t[needed_size]);
+        upload_pixels_size_ = needed_size;
       }
 
       if (plane_resource_format == viz::LUMINANCE_F16) {
@@ -1017,7 +1021,7 @@
         const int scale = 0x10000 >> (bits_per_channel - 8);
         libyuv::Convert16To8Plane(
             reinterpret_cast<uint16_t*>(video_frame->data(i)),
-            video_stride_bytes / 2, upload_pixels_.data(), upload_image_stride,
+            video_stride_bytes / 2, upload_pixels_.get(), upload_image_stride,
             scale, bytes_per_row, resource_size_pixels.height());
       } else {
         // Make a copy to reconcile stride, size and format being equal.
@@ -1025,12 +1029,12 @@
         DCHECK(plane_resource_format == viz::LUMINANCE_8 ||
                plane_resource_format == viz::RED_8);
         libyuv::CopyPlane(video_frame->data(i), video_stride_bytes,
-                          upload_pixels_.data(), upload_image_stride,
+                          upload_pixels_.get(), upload_image_stride,
                           resource_size_pixels.width(),
                           resource_size_pixels.height());
       }
 
-      pixels = &upload_pixels_[0];
+      pixels = upload_pixels_.get();
     }
 
     // Copy pixels into texture. TexSubImage2D() is applicable because
diff --git a/media/renderers/video_resource_updater.h b/media/renderers/video_resource_updater.h
index 4a4e6a5..9ea3f50 100644
--- a/media/renderers/video_resource_updater.h
+++ b/media/renderers/video_resource_updater.h
@@ -196,7 +196,8 @@
   uint32_t next_plane_resource_id_ = 1;
 
   // Temporary pixel buffer when converting between formats.
-  std::vector<uint8_t> upload_pixels_;
+  std::unique_ptr<uint8_t[]> upload_pixels_;
+  size_t upload_pixels_size_ = 0;
 
   VideoFrameResourceType frame_resource_type_;