Implement ANGLE_program_cache_control extensions.

This will give the browsers the ability to control the cache size,
query and populate the contents, and trim cache contents on memory
pressure.

BUG=angleproject:1897

Change-Id: I6edaa7d307b890223db98792d5b074e4a7fdfaa4
Reviewed-on: https://chromium-review.googlesource.com/563606
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/libANGLE/MemoryProgramCache.cpp b/src/libANGLE/MemoryProgramCache.cpp
index eccd509..1a93cd8 100644
--- a/src/libANGLE/MemoryProgramCache.cpp
+++ b/src/libANGLE/MemoryProgramCache.cpp
@@ -547,6 +547,13 @@
     return mProgramBinaryCache.get(programHash, programOut);
 }
 
+bool MemoryProgramCache::getAt(size_t index,
+                               ProgramHash *hashOut,
+                               const angle::MemoryBuffer **programOut)
+{
+    return mProgramBinaryCache.getAt(index, hashOut, programOut);
+}
+
 void MemoryProgramCache::remove(const ProgramHash &programHash)
 {
     bool result = mProgramBinaryCache.eraseByKey(programHash);
@@ -554,7 +561,6 @@
 }
 
 void MemoryProgramCache::put(const ProgramHash &program,
-                             const Context *context,
                              angle::MemoryBuffer &&binaryProgram)
 {
     const angle::MemoryBuffer *result =
@@ -576,11 +582,10 @@
 {
     angle::MemoryBuffer binaryProgram;
     Serialize(context, program, &binaryProgram);
-    put(programHash, context, std::move(binaryProgram));
+    put(programHash, std::move(binaryProgram));
 }
 
-void MemoryProgramCache::putBinary(const Context *context,
-                                   const Program *program,
+void MemoryProgramCache::putBinary(const ProgramHash &programHash,
                                    const uint8_t *binary,
                                    size_t length)
 {
@@ -589,12 +594,13 @@
     binaryProgram.resize(length);
     memcpy(binaryProgram.data(), binary, length);
 
-    // Compute the hash.
-    ProgramHash programHash;
-    ComputeHash(context, program, &programHash);
-
     // Store the binary.
-    put(programHash, context, std::move(binaryProgram));
+    const angle::MemoryBuffer *result =
+        mProgramBinaryCache.put(programHash, std::move(binaryProgram), binaryProgram.size());
+    if (!result)
+    {
+        ERR() << "Failed to store binary program in memory cache, program is too large.";
+    }
 }
 
 void MemoryProgramCache::clear()
@@ -603,4 +609,29 @@
     mIssuedWarnings = 0;
 }
 
+void MemoryProgramCache::resize(size_t maxCacheSizeBytes)
+{
+    mProgramBinaryCache.resize(maxCacheSizeBytes);
+}
+
+size_t MemoryProgramCache::entryCount() const
+{
+    return mProgramBinaryCache.entryCount();
+}
+
+size_t MemoryProgramCache::trim(size_t limit)
+{
+    return mProgramBinaryCache.shrinkToSize(limit);
+}
+
+size_t MemoryProgramCache::size() const
+{
+    return mProgramBinaryCache.size();
+}
+
+size_t MemoryProgramCache::maxSize() const
+{
+    return mProgramBinaryCache.maxSize();
+}
+
 }  // namespace gl