OSDN Git Service

Revert "Revert "DO NOT MERGE ANYWHERE: Goldfish DMA-based gralloc""
authorLingfeng Yang <lfy@google.com>
Wed, 30 Nov 2016 00:52:35 +0000 (00:52 +0000)
committerLingfeng Yang <lfy@google.com>
Wed, 30 Nov 2016 00:54:02 +0000 (16:54 -0800)
This reverts commit 9b166b966d6f03f13f65d3134f9c5e1133ec10e2.

Change-Id: I9b10b45d1ebd3b51ede2f75cc8ab403914b0d777

22 files changed:
system/OpenglSystemCommon/Android.mk
system/OpenglSystemCommon/FormatConversions.cpp [new file with mode: 0644]
system/OpenglSystemCommon/FormatConversions.h [new file with mode: 0644]
system/OpenglSystemCommon/HostConnection.cpp
system/OpenglSystemCommon/HostConnection.h
system/OpenglSystemCommon/ProcessPipe.cpp
system/OpenglSystemCommon/QemuPipeStream.cpp
system/OpenglSystemCommon/QemuPipeStream.h
system/OpenglSystemCommon/goldfish_dma.cpp [new file with mode: 0644]
system/OpenglSystemCommon/goldfish_dma.h [new file with mode: 0644]
system/OpenglSystemCommon/gralloc_cb.h
system/OpenglSystemCommon/qemu_pipe.h [new file with mode: 0644]
system/egl/egl.cpp
system/gralloc/gralloc.cpp
system/renderControl_enc/renderControl_client_context.cpp
system/renderControl_enc/renderControl_client_context.h
system/renderControl_enc/renderControl_client_proc.h
system/renderControl_enc/renderControl_enc.cpp
system/renderControl_enc/renderControl_enc.h
system/renderControl_enc/renderControl_entry.cpp
system/renderControl_enc/renderControl_ftable.h
system/renderControl_enc/renderControl_opcodes.h

index acf9ce1..9853f29 100644 (file)
@@ -4,6 +4,8 @@ $(call emugl-begin-shared-library,libOpenglSystemCommon)
 $(call emugl-import,libGLESv1_enc libGLESv2_enc lib_renderControl_enc)
 
 LOCAL_SRC_FILES := \
+    goldfish_dma.cpp \
+    FormatConversions.cpp \
     HostConnection.cpp \
     ProcessPipe.cpp    \
     QemuPipeStream.cpp \
diff --git a/system/OpenglSystemCommon/FormatConversions.cpp b/system/OpenglSystemCommon/FormatConversions.cpp
new file mode 100644 (file)
index 0000000..5fcffa3
--- /dev/null
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2016 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "FormatConversions.h"
+
+#include <cutils/log.h>
+#include <string.h>
+
+#define DEBUG 0
+
+#if DEBUG
+#define DD(...) ALOGD(...)
+#else
+#define DD(...)
+#endif
+
+void get_yv12_offsets(int width, int height,
+                             uint32_t* yStride_out,
+                             uint32_t* cStride_out,
+                             uint32_t* totalSz_out) {
+    uint32_t align = 16;
+    uint32_t yStride = (width + (align - 1)) & ~(align-1);
+    uint32_t uvStride = (yStride / 2 + (align - 1)) & ~(align-1);
+    uint32_t uvHeight = height / 2;
+    uint32_t sz = yStride * height + 2 * (uvHeight * uvStride);
+
+    if (yStride_out) *yStride_out = yStride;
+    if (cStride_out) *cStride_out = uvStride;
+    if (totalSz_out) *totalSz_out = sz;
+}
+
+void get_yuv420p_offsets(int width, int height,
+                                uint32_t* yStride_out,
+                                uint32_t* cStride_out,
+                                uint32_t* totalSz_out) {
+    uint32_t align = 1;
+    uint32_t yStride = (width + (align - 1)) & ~(align-1);
+    uint32_t uvStride = (yStride / 2 + (align - 1)) & ~(align-1);
+    uint32_t uvHeight = height / 2;
+    uint32_t sz = yStride * height + 2 * (uvHeight * uvStride);
+
+    if (yStride_out) *yStride_out = yStride;
+    if (cStride_out) *cStride_out = uvStride;
+    if (totalSz_out) *totalSz_out = sz;
+}
+
+signed clamp_rgb(signed value) {
+    if (value > 255) {
+        value = 255;
+    } else if (value < 0) {
+        value = 0;
+    }
+    return value;
+}
+
+void rgb565_to_yv12(char* dest, char* src, int width, int height,
+        int left, int top, int right, int bottom) {
+    int align = 16;
+    int yStride = (width + (align -1)) & ~(align-1);
+    int cStride = (yStride / 2 + (align - 1)) & ~(align-1);
+    int yOffset = 0;
+    int cSize = cStride * height/2;
+
+    uint16_t *rgb_ptr0 = (uint16_t *)src;
+    uint8_t *yv12_y0 = (uint8_t *)dest;
+    uint8_t *yv12_v0 = yv12_y0 + yStride * height;
+    uint8_t *yv12_u0 = yv12_v0 + cSize;
+
+    for (int j = top; j <= bottom; ++j) {
+        uint8_t *yv12_y = yv12_y0 + j * yStride;
+        uint8_t *yv12_v = yv12_v0 + (j/2) * cStride;
+        uint8_t *yv12_u = yv12_v + cSize;
+        uint16_t *rgb_ptr = rgb_ptr0 + j * width;
+        bool jeven = (j & 1) == 0;
+        for (int i = left; i <= right; ++i) {
+            uint8_t r = ((rgb_ptr[i]) >> 11) & 0x01f;
+            uint8_t g = ((rgb_ptr[i]) >> 5) & 0x03f;
+            uint8_t b = (rgb_ptr[i]) & 0x01f;
+            // convert to 8bits
+            // http://stackoverflow.com/questions/2442576/how-does-one-convert-16-bit-rgb565-to-24-bit-rgb888
+            uint8_t R = (r * 527 + 23) >> 6;
+            uint8_t G = (g * 259 + 33) >> 6;
+            uint8_t B = (b * 527 + 23) >> 6;
+            // convert to YV12
+            // frameworks/base/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
+            yv12_y[i] = clamp_rgb((77 * R + 150 * G +  29 * B) >> 8);
+            bool ieven = (i & 1) == 0;
+            if (jeven && ieven) {
+                yv12_u[i] = clamp_rgb((( -43 * R - 85 * G + 128 * B) >> 8) + 128);
+                yv12_v[i] = clamp_rgb((( 128 * R - 107 * G - 21 * B) >> 8) + 128);
+            }
+        }
+    }
+}
+
+void rgb888_to_yv12(char* dest, char* src, int width, int height,
+        int left, int top, int right, int bottom) {
+    DD("%s convert %d by %d", __func__, width, height);
+    int align = 16;
+    int yStride = (width + (align -1)) & ~(align-1);
+    int cStride = (yStride / 2 + (align - 1)) & ~(align-1);
+    int yOffset = 0;
+    int cSize = cStride * height/2;
+    int rgb_stride = 3;
+
+    uint8_t *rgb_ptr0 = (uint8_t *)src;
+    uint8_t *yv12_y0 = (uint8_t *)dest;
+    uint8_t *yv12_v0 = yv12_y0 + yStride * height;
+    uint8_t *yv12_u0 = yv12_v0 + cSize;
+
+    for (int j = top; j <= bottom; ++j) {
+        uint8_t *yv12_y = yv12_y0 + j * yStride;
+        uint8_t *yv12_v = yv12_v0 + (j/2) * cStride;
+        uint8_t *yv12_u = yv12_v + cSize;
+        uint8_t  *rgb_ptr = rgb_ptr0 + j * width*rgb_stride;
+        bool jeven = (j & 1) == 0;
+        for (int i = left; i <= right; ++i) {
+            uint8_t R = rgb_ptr[i*rgb_stride];
+            uint8_t G = rgb_ptr[i*rgb_stride+1];
+            uint8_t B = rgb_ptr[i*rgb_stride+2];
+            // convert to YV12
+            // frameworks/base/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
+            yv12_y[i] = clamp_rgb((77 * R + 150 * G +  29 * B) >> 8);
+            bool ieven = (i & 1) == 0;
+            if (jeven && ieven) {
+                yv12_u[i] = clamp_rgb((( -43 * R - 85 * G + 128 * B) >> 8) + 128);
+                yv12_v[i] = clamp_rgb((( 128 * R - 107 * G - 21 * B) >> 8) + 128);
+            }
+        }
+    }
+}
+
+void rgb888_to_yuv420p(char* dest, char* src, int width, int height,
+        int left, int top, int right, int bottom) {
+    DD("%s convert %d by %d", __func__, width, height);
+    int yStride = width;
+    int cStride = yStride / 2;
+    int yOffset = 0;
+    int cSize = cStride * height/2;
+    int rgb_stride = 3;
+
+    uint8_t *rgb_ptr0 = (uint8_t *)src;
+    uint8_t *yv12_y0 = (uint8_t *)dest;
+    uint8_t *yv12_u0 = yv12_y0 + yStride * height;
+    uint8_t *yv12_v0 = yv12_u0 + cSize;
+
+    for (int j = top; j <= bottom; ++j) {
+        uint8_t *yv12_y = yv12_y0 + j * yStride;
+        uint8_t *yv12_u = yv12_u0 + (j/2) * cStride;
+        uint8_t *yv12_v = yv12_u + cStride;
+        uint8_t  *rgb_ptr = rgb_ptr0 + j * width*rgb_stride;
+        bool jeven = (j & 1) == 0;
+        for (int i = left; i <= right; ++i) {
+            uint8_t R = rgb_ptr[i*rgb_stride];
+            uint8_t G = rgb_ptr[i*rgb_stride+1];
+            uint8_t B = rgb_ptr[i*rgb_stride+2];
+            // convert to YV12
+            // frameworks/base/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
+            yv12_y[i] = clamp_rgb((77 * R + 150 * G +  29 * B) >> 8);
+            bool ieven = (i & 1) == 0;
+            if (jeven && ieven) {
+                yv12_u[i] = clamp_rgb((( -43 * R - 85 * G + 128 * B) >> 8) + 128);
+                yv12_v[i] = clamp_rgb((( 128 * R - 107 * G - 21 * B) >> 8) + 128);
+            }
+        }
+    }
+}
+// YV12 is aka YUV420Planar, or YUV420p; the only difference is that YV12 has
+// certain stride requirements for Y and UV respectively.
+void yv12_to_rgb565(char* dest, char* src, int width, int height,
+        int left, int top, int right, int bottom) {
+    DD("%s convert %d by %d", __func__, width, height);
+    int align = 16;
+    int yStride = (width + (align -1)) & ~(align-1);
+    int cStride = (yStride / 2 + (align - 1)) & ~(align-1);
+    int yOffset = 0;
+    int cSize = cStride * height/2;
+
+    uint16_t *rgb_ptr0 = (uint16_t *)dest;
+    uint8_t *yv12_y0 = (uint8_t *)src;
+    uint8_t *yv12_v0 = yv12_y0 + yStride * height;
+    uint8_t *yv12_u0 = yv12_v0 + cSize;
+
+    for (int j = top; j <= bottom; ++j) {
+        uint8_t *yv12_y = yv12_y0 + j * yStride;
+        uint8_t *yv12_v = yv12_v0 + (j/2) * cStride;
+        uint8_t *yv12_u = yv12_v + cSize;
+        uint16_t *rgb_ptr = rgb_ptr0 + (j-top) * (right-left+1);
+        for (int i = left; i <= right; ++i) {
+            // convert to rgb
+            // frameworks/av/media/libstagefright/colorconversion/ColorConverter.cpp
+            signed y1 = (signed)yv12_y[i] - 16;
+            signed u = (signed)yv12_u[i / 2] - 128;
+            signed v = (signed)yv12_v[i / 2] - 128;
+
+            signed u_b = u * 517;
+            signed u_g = -u * 100;
+            signed v_g = -v * 208;
+            signed v_r = v * 409;
+
+            signed tmp1 = y1 * 298;
+            signed b1 = clamp_rgb((tmp1 + u_b) / 256);
+            signed g1 = clamp_rgb((tmp1 + v_g + u_g) / 256);
+            signed r1 = clamp_rgb((tmp1 + v_r) / 256);
+
+            uint16_t rgb1 = ((r1 >> 3) << 11) | ((g1 >> 2) << 5) | (b1 >> 3);
+
+            rgb_ptr[i-left] = rgb1;
+        }
+    }
+}
+
+// YV12 is aka YUV420Planar, or YUV420p; the only difference is that YV12 has
+// certain stride requirements for Y and UV respectively.
+void yv12_to_rgb888(char* dest, char* src, int width, int height,
+        int left, int top, int right, int bottom) {
+    DD("%s convert %d by %d", __func__, width, height);
+    int align = 16;
+    int yStride = (width + (align -1)) & ~(align-1);
+    int cStride = (yStride / 2 + (align - 1)) & ~(align-1);
+    int yOffset = 0;
+    int cSize = cStride * height/2;
+    int rgb_stride = 3;
+
+    uint8_t *rgb_ptr0 = (uint8_t *)dest;
+    uint8_t *yv12_y0 = (uint8_t *)src;
+    uint8_t *yv12_v0 = yv12_y0 + yStride * height;
+    uint8_t *yv12_u0 = yv12_v0 + cSize;
+
+    for (int j = top; j <= bottom; ++j) {
+        uint8_t *yv12_y = yv12_y0 + j * yStride;
+        uint8_t *yv12_v = yv12_v0 + (j/2) * cStride;
+        uint8_t *yv12_u = yv12_v + cSize;
+        uint8_t *rgb_ptr = rgb_ptr0 + (j-top) * (right-left+1) * rgb_stride;
+        for (int i = left; i <= right; ++i) {
+            // convert to rgb
+            // frameworks/av/media/libstagefright/colorconversion/ColorConverter.cpp
+            signed y1 = (signed)yv12_y[i] - 16;
+            signed u = (signed)yv12_u[i / 2] - 128;
+            signed v = (signed)yv12_v[i / 2] - 128;
+
+            signed u_b = u * 517;
+            signed u_g = -u * 100;
+            signed v_g = -v * 208;
+            signed v_r = v * 409;
+
+            signed tmp1 = y1 * 298;
+            signed b1 = clamp_rgb((tmp1 + u_b) / 256);
+            signed g1 = clamp_rgb((tmp1 + v_g + u_g) / 256);
+            signed r1 = clamp_rgb((tmp1 + v_r) / 256);
+
+            rgb_ptr[(i-left)*rgb_stride] = r1;
+            rgb_ptr[(i-left)*rgb_stride+1] = g1;
+            rgb_ptr[(i-left)*rgb_stride+2] = b1;
+        }
+    }
+}
+
+// YV12 is aka YUV420Planar, or YUV420p; the only difference is that YV12 has
+// certain stride requirements for Y and UV respectively.
+void yuv420p_to_rgb888(char* dest, char* src, int width, int height,
+        int left, int top, int right, int bottom) {
+    DD("%s convert %d by %d", __func__, width, height);
+    int yStride = width;
+    int cStride = yStride / 2;
+    int yOffset = 0;
+    int cSize = cStride * height/2;
+    int rgb_stride = 3;
+
+    uint8_t *rgb_ptr0 = (uint8_t *)dest;
+    uint8_t *yv12_y0 = (uint8_t *)src;
+    uint8_t *yv12_u0 = yv12_y0 + yStride * height;
+    uint8_t *yv12_v0 = yv12_u0 + cSize;
+
+    for (int j = top; j <= bottom; ++j) {
+        uint8_t *yv12_y = yv12_y0 + j * yStride;
+        uint8_t *yv12_u = yv12_u0 + (j/2) * cStride;
+        uint8_t *yv12_v = yv12_u + cSize;
+        uint8_t *rgb_ptr = rgb_ptr0 + (j-top) * (right-left+1) * rgb_stride;
+        for (int i = left; i <= right; ++i) {
+            // convert to rgb
+            // frameworks/av/media/libstagefright/colorconversion/ColorConverter.cpp
+            signed y1 = (signed)yv12_y[i] - 16;
+            signed u = (signed)yv12_u[i / 2] - 128;
+            signed v = (signed)yv12_v[i / 2] - 128;
+
+            signed u_b = u * 517;
+            signed u_g = -u * 100;
+            signed v_g = -v * 208;
+            signed v_r = v * 409;
+
+            signed tmp1 = y1 * 298;
+            signed b1 = clamp_rgb((tmp1 + u_b) / 256);
+            signed g1 = clamp_rgb((tmp1 + v_g + u_g) / 256);
+            signed r1 = clamp_rgb((tmp1 + v_r) / 256);
+
+            rgb_ptr[(i-left)*rgb_stride] = r1;
+            rgb_ptr[(i-left)*rgb_stride+1] = g1;
+            rgb_ptr[(i-left)*rgb_stride+2] = b1;
+        }
+    }
+}
+
+void copy_rgb_buffer(char* _dst, char* raw_data,
+                            int width, int height, int top, int left,
+                            int bpp) {
+    char* dst = _dst;
+    int dst_line_len = width * bpp;
+    int src_line_len = width * bpp;
+    char *src = (char *)raw_data + top*src_line_len + left*bpp;
+    for (int y = 0; y < height; y++)
+        memcpy(dst, src, dst_line_len);
+    src += src_line_len;
+    dst += dst_line_len;
+}
diff --git a/system/OpenglSystemCommon/FormatConversions.h b/system/OpenglSystemCommon/FormatConversions.h
new file mode 100644 (file)
index 0000000..e844be8
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2016 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __GOLDFISH_FORMATCONVERSIONS_H__
+#define __GOLDFISH_FORMATCONVERSIONS_H__
+
+#include <inttypes.h>
+
+// format conversions and helper functions
+void get_yv12_offsets(int width, int height,
+                      uint32_t* yStride_out,
+                      uint32_t* cStride_out,
+                      uint32_t* totalSz_out);
+void get_yuv420p_offsets(int width, int height,
+                         uint32_t* yStride_out,
+                         uint32_t* cStride_out,
+                         uint32_t* totalSz_out);
+signed clamp_rgb(signed value);
+void rgb565_to_yv12(char* dest, char* src, int width, int height,
+                    int left, int top, int right, int bottom);
+void rgb888_to_yv12(char* dest, char* src, int width, int height,
+                    int left, int top, int right, int bottom);
+void rgb888_to_yuv420p(char* dest, char* src, int width, int height,
+                       int left, int top, int right, int bottom);
+void yv12_to_rgb565(char* dest, char* src, int width, int height,
+                    int left, int top, int right, int bottom);
+void yv12_to_rgb888(char* dest, char* src, int width, int height,
+                    int left, int top, int right, int bottom);
+void yuv420p_to_rgb888(char* dest, char* src, int width, int height,
+                       int left, int top, int right, int bottom);
+void copy_rgb_buffer(char* _dst, char* raw_data,
+                            int width, int height, int top, int left,
+                            int bpp);
+#endif
index cc8879f..bb03457 100644 (file)
@@ -80,6 +80,7 @@ HostConnection *HostConnection::get() {
                 return NULL;
             }
             con->m_stream = stream;
+            con->m_pipeFd = stream->getSocket();
         }
         else /* !useQemuPipe */
         {
@@ -152,6 +153,7 @@ ExtendedRCEncoderContext *HostConnection::rcEncoder()
         m_rcEnc = new ExtendedRCEncoderContext(m_stream, checksumHelper());
         setChecksumHelper(m_rcEnc);
         queryAndSetSyncImpl(m_rcEnc);
+        queryAndSetDmaImpl(m_rcEnc);
         processPipeInit(m_rcEnc);
     }
     return m_rcEnc;
@@ -234,3 +236,16 @@ void HostConnection::queryAndSetSyncImpl(ExtendedRCEncoderContext *rcEnc) {
     }
 #endif
 }
+
+void HostConnection::queryAndSetDmaImpl(ExtendedRCEncoderContext *rcEnc) {
+    std::string glExtensions = queryGLExtensions(rcEnc);
+#if PLATFORM_SDK_VERSION <= 16 || (!defined(__i386__) && !defined(__x86_64__))
+    rcEnc->setDmaImpl(DMA_IMPL_NONE);
+#else
+    if (glExtensions.find(kDmaExtStr_v1) != std::string::npos) {
+        rcEnc->setDmaImpl(DMA_IMPL_v1);
+    } else {
+        rcEnc->setDmaImpl(DMA_IMPL_NONE);
+    }
+#endif
+}
index c460343..b81dd06 100644 (file)
@@ -19,6 +19,7 @@
 #include "IOStream.h"
 #include "renderControl_enc.h"
 #include "ChecksumCalculator.h"
+#include "goldfish_dma.h"
 
 #include <string>
 
@@ -41,6 +42,7 @@ enum SyncImpl {
     SYNC_IMPL_NONE = 0,
     SYNC_IMPL_NATIVE_SYNC = 1
 };
+
 // Interface:
 // If this GL extension string shows up, we use
 // SYNC_IMPL_NATIVE_SYNC, otherwise we use SYNC_IMPL_NONE.
@@ -49,16 +51,44 @@ enum SyncImpl {
 // otherwise, we do not use the feature.
 static const char kRCNativeSync[] = "ANDROID_EMU_native_sync_v2";
 
+// DMA for OpenGL
+enum DmaImpl {
+    DMA_IMPL_NONE = 0,
+    DMA_IMPL_v1 = 1,
+};
+
+static const char kDmaExtStr_v1[] = "ANDROID_EMU_dma_v1";
+
 // ExtendedRCEncoderContext is an extended version of renderControl_encoder_context_t
 // that will be used to track SyncImpl.
 class ExtendedRCEncoderContext : public renderControl_encoder_context_t {
 public:
     ExtendedRCEncoderContext(IOStream *stream, ChecksumCalculator *checksumCalculator)
-        : renderControl_encoder_context_t(stream, checksumCalculator) { }
+        : renderControl_encoder_context_t(stream, checksumCalculator) {
+        m_dmaCxt = NULL;
+        }
     void setSyncImpl(SyncImpl syncImpl) { m_syncImpl = syncImpl; }
+    void setDmaImpl(DmaImpl dmaImpl) { m_dmaImpl = dmaImpl; }
     bool hasNativeSync() const { return m_syncImpl == SYNC_IMPL_NATIVE_SYNC; }
+    DmaImpl getDmaVersion() const { return m_dmaImpl; }
+    void bindDmaContext(struct goldfish_dma_context* cxt) { m_dmaCxt = cxt; }
+    virtual uint64_t lockAndWriteDma(void* data, uint32_t size) {
+        ALOGV("%s: call", __FUNCTION__);
+        if (!m_dmaCxt) {
+            ALOGE("%s: ERROR: No DMA context bound!",
+                  __FUNCTION__);
+            return 0;
+        }
+        goldfish_dma_lock(m_dmaCxt);
+        goldfish_dma_write(m_dmaCxt, data, size);
+        uint64_t paddr = goldfish_dma_guest_paddr(m_dmaCxt);
+        ALOGV("%s: paddr=0x%llx", __FUNCTION__, paddr);
+        return paddr;
+    }
 private:
     SyncImpl m_syncImpl;
+    DmaImpl m_dmaImpl;
+    struct goldfish_dma_context* m_dmaCxt;
 };
 
 class HostConnection
@@ -85,6 +115,8 @@ public:
 
     bool isGrallocOnly() const { return m_grallocOnly; }
 
+    int getPipeFd() const { return m_pipeFd; }
+
 private:
     HostConnection();
     static gl_client_context_t  *s_getGLContext();
@@ -95,6 +127,7 @@ private:
     // should be called when m_rcEnc is created
     void setChecksumHelper(ExtendedRCEncoderContext *rcEnc);
     void queryAndSetSyncImpl(ExtendedRCEncoderContext *rcEnc);
+    void queryAndSetDmaImpl(ExtendedRCEncoderContext *rcEnc);
 
 private:
     IOStream *m_stream;
@@ -104,6 +137,7 @@ private:
     ChecksumCalculator m_checksumHelper;
     std::string m_glExtensions;
     bool m_grallocOnly;
+    int m_pipeFd;
 };
 
 #endif
index e638236..127f273 100644 (file)
 */
 
 #include "renderControl_enc.h"
+#include "qemu_pipe.h"
 
 #include <cutils/log.h>
 #include <pthread.h>
-#if PLATFORM_SDK_VERSION > 24
-#include <system/qemu_pipe.h>
-#else // PLATFORM_SDK_VERSION
-#include <hardware/qemu_pipe.h>
-#endif //PLATFORM_SDK_VERSION
 
 static int                sProcPipe = 0;
 static pthread_once_t     sProcPipeOnce = PTHREAD_ONCE_INIT;
@@ -79,4 +75,4 @@ bool processPipeInit(renderControl_encoder_context_t *rcEnc) {
     if (!sProcPipe) return false;
     rcEnc->rcSetPuid(rcEnc, sProcUID);
     return true;
-}
\ No newline at end of file
+}
index de9f3af..b49fc57 100644 (file)
 * limitations under the License.
 */
 #include "QemuPipeStream.h"
-#if PLATFORM_SDK_VERSION > 24
-#include <system/qemu_pipe.h>
-#else // PLATFORM_SDK_VERSION
-#include <hardware/qemu_pipe.h>
-#endif //PLATFORM_SDK_VERSION
+#include "qemu_pipe.h"
+
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -60,7 +57,10 @@ int QemuPipeStream::connect(void)
 #else // PLATFORM_SDK_VERSION
      m_sock = qemu_pipe_open("opengles");
 #endif // PLATFORM_SDK_VERSION
-    if (!valid()) return -1;
+    if (!valid()) {
+        ALOGE("%s: failed with fd %d errno %d", __FUNCTION__, m_sock, errno);
+        return -1;
+    }
     return 0;
 }
 
@@ -132,6 +132,10 @@ int QemuPipeStream::writeFully(const void *buf, size_t len)
     return retval;
 }
 
+int QemuPipeStream::getSocket() const {
+    return m_sock;
+}
+
 const unsigned char *QemuPipeStream::readFully(void *buf, size_t len)
 {
     //DBG(">> QemuPipeStream::readFully %d\n", len);
index 57ee399..15f74e6 100644 (file)
@@ -41,6 +41,7 @@ public:
 
     virtual int writeFully(const void *buf, size_t len);
 
+    int getSocket() const;
 private:
     int m_sock;
     size_t m_bufsize;
diff --git a/system/OpenglSystemCommon/goldfish_dma.cpp b/system/OpenglSystemCommon/goldfish_dma.cpp
new file mode 100644 (file)
index 0000000..ccb8fda
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2016 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "goldfish_dma.h"
+#include "qemu_pipe.h"
+
+#include <cutils/log.h>
+#include <sys/mman.h>
+#include <stdlib.h>
+#include <string.h>
+
+int goldfish_dma_lock(struct goldfish_dma_context* cxt) {
+    struct goldfish_dma_ioctl_info info;
+
+    return ioctl(cxt->fd, GOLDFISH_DMA_IOC_LOCK, &info);
+}
+
+int goldfish_dma_unlock(struct goldfish_dma_context* cxt) {
+    struct goldfish_dma_ioctl_info info;
+
+    return ioctl(cxt->fd, GOLDFISH_DMA_IOC_UNLOCK, &info);
+}
+
+int goldfish_dma_create_region(uint32_t sz, struct goldfish_dma_context* res) {
+
+    res->fd = qemu_pipe_open("opengles");
+    res->mapped = NULL;
+    res->sz = 0;
+
+    if (res->fd > 0) {
+        // now alloc
+        struct goldfish_dma_ioctl_info info;
+        info.size = sz;
+        int alloc_res = ioctl(res->fd, GOLDFISH_DMA_IOC_CREATE_REGION, &info);
+
+        if (alloc_res) {
+            ALOGE("%s: failed to allocate DMA region. errno=%d",
+                  __FUNCTION__, errno);
+            close(res->fd);
+            res->fd = -1;
+            return alloc_res;
+        }
+
+        res->sz = sz;
+        ALOGV("%s: successfully allocated goldfish DMA region with size %lu cxt=%p",
+              __FUNCTION__, sz, res);
+        return 0;
+    } else {
+        ALOGE("%s: could not obtain fd to device! fd %d errno=%d\n",
+              __FUNCTION__, res->fd, errno);
+        return ENODEV;
+    }
+}
+
+void* goldfish_dma_map(struct goldfish_dma_context* cxt) {
+    ALOGV("%s: on fd %d errno=%d", __FUNCTION__, cxt->fd, errno);
+    cxt->mapped = mmap(0, cxt->sz, PROT_WRITE, MAP_SHARED, cxt->fd, 0);
+    ALOGV("%s: mapped addr=%p errno=%d", __FUNCTION__, cxt->mapped, errno);
+
+    if (cxt->mapped == MAP_FAILED) {
+        cxt->mapped = NULL;
+    }
+    return cxt->mapped;
+}
+
+int goldfish_dma_unmap(struct goldfish_dma_context* cxt) {
+    munmap(cxt->mapped, cxt->sz);
+    cxt->mapped = NULL;
+    cxt->sz = 0;
+    return 0;
+}
+
+void goldfish_dma_write(struct goldfish_dma_context* cxt,
+                               void* to_write,
+                               uint32_t sz) {
+    ALOGV("%s: mapped addr=%p", __FUNCTION__, cxt->mapped);
+    memcpy(cxt->mapped, to_write, sz);
+}
+
+void goldfish_dma_free(goldfish_dma_context* cxt) {
+    struct goldfish_dma_ioctl_info info;
+    close(cxt->fd);
+}
+
+uint64_t goldfish_dma_guest_paddr(struct goldfish_dma_context* cxt) {
+    struct goldfish_dma_ioctl_info info;
+    ioctl(cxt->fd, GOLDFISH_DMA_IOC_GETOFF, &info);
+    return info.phys_begin;
+}
diff --git a/system/OpenglSystemCommon/goldfish_dma.h b/system/OpenglSystemCommon/goldfish_dma.h
new file mode 100644 (file)
index 0000000..b314f8d
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2016 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef ANDROID_INCLUDE_HARDWARE_GOLDFISH_DMA_H
+#define ANDROID_INCLUDE_HARDWARE_GOLDFISH_DMA_H
+
+#include <errno.h>
+#include <linux/ioctl.h>
+#include <linux/types.h>
+#include <sys/cdefs.h>
+#include <fcntl.h>
+#include <stdlib.h>
+
+/* There is an ioctl associated with goldfish dma driver.
+ * Make it conflict with ioctls that are not likely to be used
+ * in the emulator.
+ * 'G' 00-3F   drivers/misc/sgi-gru/grulib.h   conflict!
+ * 'G' 00-0F   linux/gigaset_dev.h     conflict!
+ */
+#define GOLDFISH_DMA_IOC_MAGIC 'G'
+
+#define GOLDFISH_DMA_IOC_LOCK                  _IOWR(GOLDFISH_DMA_IOC_MAGIC, 0, struct goldfish_dma_ioctl_info)
+#define GOLDFISH_DMA_IOC_UNLOCK                        _IOWR(GOLDFISH_DMA_IOC_MAGIC, 1, struct goldfish_dma_ioctl_info)
+#define GOLDFISH_DMA_IOC_GETOFF                        _IOWR(GOLDFISH_DMA_IOC_MAGIC, 2, struct goldfish_dma_ioctl_info)
+#define GOLDFISH_DMA_IOC_CREATE_REGION _IOWR(GOLDFISH_DMA_IOC_MAGIC, 3, struct goldfish_dma_ioctl_info)
+
+struct goldfish_dma_ioctl_info {
+    uint64_t phys_begin;
+    uint64_t size;
+};
+
+// userspace interface
+struct goldfish_dma_context {
+    int fd;
+    void* mapped;
+    uint64_t sz; // size of reservation
+};
+
+int goldfish_dma_lock(struct goldfish_dma_context* cxt);
+int goldfish_dma_unlock(struct goldfish_dma_context* cxt);
+int goldfish_dma_create_region(uint32_t sz, struct goldfish_dma_context* res);
+
+void* goldfish_dma_map(struct goldfish_dma_context* cxt);
+int goldfish_dma_unmap(struct goldfish_dma_context* cxt);
+
+void goldfish_dma_write(struct goldfish_dma_context* cxt,
+                        void* to_write,
+                        uint32_t sz);
+
+void goldfish_dma_free(goldfish_dma_context* cxt);
+uint64_t goldfish_dma_guest_paddr(struct goldfish_dma_context* cxt);
+
+#endif
index d2d6f35..04a7040 100644 (file)
 #include <hardware/gralloc.h>
 #include <cutils/native_handle.h>
 
+#include "goldfish_dma.h"
+
 #define BUFFER_HANDLE_MAGIC ((int)0xabfabfab)
 #define CB_HANDLE_NUM_INTS(nfds) (int)((sizeof(cb_handle_t) - (nfds)*sizeof(int)) / sizeof(int))
 
+// Tell the emulator which gralloc formats
+// need special handling.
+enum EmulatorFrameworkFormat {
+    FRAMEWORK_FORMAT_GL_COMPATIBLE = 0,
+    FRAMEWORK_FORMAT_YV12 = 1,
+    FRAMEWORK_FORMAT_YUV_420_888 = 2,
+};
+
 //
 // Our buffer handle structure
 //
@@ -31,7 +41,8 @@ struct cb_handle_t : public native_handle {
 
     cb_handle_t(int p_fd, int p_ashmemSize, int p_usage,
                 int p_width, int p_height, int p_frameworkFormat,
-                int p_format, int p_glFormat, int p_glType) :
+                int p_format, int p_glFormat, int p_glType,
+                EmulatorFrameworkFormat p_emuFrameworkFormat) :
         fd(p_fd),
         magic(BUFFER_HANDLE_MAGIC),
         usage(p_usage),
@@ -49,8 +60,11 @@ struct cb_handle_t : public native_handle {
         lockedTop(0),
         lockedWidth(0),
         lockedHeight(0),
-        hostHandle(0)
+        hostHandle(0),
+        emuFrameworkFormat(p_emuFrameworkFormat)
     {
+        goldfish_dma.fd = -1;
+        dmafd = -1;
         version = sizeof(native_handle);
         numFds = 0;
         numInts = CB_HANDLE_NUM_INTS(numFds);
@@ -62,15 +76,20 @@ struct cb_handle_t : public native_handle {
 
     void setFd(int p_fd) {
         if (p_fd >= 0) {
-            numFds = 1;
-        }
-        else {
-            numFds = 0;
+            numFds++;
         }
         fd = p_fd;
         numInts = CB_HANDLE_NUM_INTS(numFds);
     }
 
+    void setDmaFd(int fd) {
+        if (fd >= 0) {
+            numFds++;
+        }
+        dmafd = fd;
+        numInts = CB_HANDLE_NUM_INTS(numFds);
+    }
+
     static bool validate(const cb_handle_t* hnd) {
         return (hnd &&
                 hnd->version == sizeof(native_handle) &&
@@ -84,6 +103,7 @@ struct cb_handle_t : public native_handle {
 
     // file-descriptors
     int fd;  // ashmem fd (-1 of ashmem region did not allocated, i.e. no SW access needed)
+    int dmafd; // goldfish dma fd.
 
     // ints
     int magic;              // magic number in order to validate a pointer to be a cb_handle_t
@@ -108,6 +128,10 @@ struct cb_handle_t : public native_handle {
     int lockedWidth;
     int lockedHeight;
     uint32_t hostHandle;
+
+    goldfish_dma_context goldfish_dma;
+    uint32_t goldfish_dma_buf_size;
+    EmulatorFrameworkFormat emuFrameworkFormat;
 };
 
 
diff --git a/system/OpenglSystemCommon/qemu_pipe.h b/system/OpenglSystemCommon/qemu_pipe.h
new file mode 100644 (file)
index 0000000..2328221
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+* Copyright (C) 2016 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+#if PLATFORM_SDK_VERSION > 24
+#include <system/qemu_pipe.h>
+#else // PLATFORM_SDK_VERSION
+#include <hardware/qemu_pipe.h>
+#endif //PLATFORM_SDK_VERSION
index 3696cdd..db256c0 100644 (file)
@@ -554,8 +554,7 @@ EGLBoolean egl_pbuffer_surface_t::init(GLenum pixelFormat)
         return EGL_FALSE;
     }
 
-    rcColorBuffer = rcEnc->rcCreateColorBuffer(rcEnc, getWidth(), getHeight(),
-            pixelFormat);
+    rcColorBuffer = rcEnc->rcCreateColorBuffer(rcEnc, getWidth(), getHeight(), pixelFormat);
     if (!rcColorBuffer) {
         ALOGE("rcCreateColorBuffer returned 0");
         return EGL_FALSE;
index 9797f5f..5e590a6 100644 (file)
@@ -22,6 +22,8 @@
 #include <dlfcn.h>
 #include <sys/mman.h>
 #include "gralloc_cb.h"
+#include "goldfish_dma.h"
+#include "FormatConversions.h"
 #include "HostConnection.h"
 #include "ProcessPipe.h"
 #include "glUtils.h"
@@ -94,6 +96,7 @@ static int map_buffer(cb_handle_t *cb, void **vaddr)
     void *addr = mmap(0, cb->ashmemSize, PROT_READ | PROT_WRITE,
                       MAP_SHARED, cb->fd, 0);
     if (addr == MAP_FAILED) {
+        ALOGE("%s: failed to map ashmem region!", __FUNCTION__);
         return -errno;
     }
 
@@ -106,15 +109,7 @@ static int map_buffer(cb_handle_t *cb, void **vaddr)
 
 #define DEFINE_HOST_CONNECTION \
     HostConnection *hostCon = HostConnection::get(); \
-    renderControl_encoder_context_t *rcEnc = (hostCon ? hostCon->rcEncoder() : NULL)
-
-#define EXIT_GRALLOCONLY_HOST_CONNECTION \
-    HostConnection *hostCon = HostConnection::get(); \
-    if (hostCon && hostCon->isGrallocOnly()) { \
-        ALOGD("%s: exiting HostConnection (is buffer-handling thread)", \
-              __FUNCTION__); \
-        HostConnection::exit(); \
-    }
+    ExtendedRCEncoderContext *rcEnc = (hostCon ? hostCon->rcEncoder() : NULL)
 
 #define DEFINE_AND_VALIDATE_HOST_CONNECTION \
     HostConnection *hostCon = HostConnection::get(); \
@@ -122,7 +117,7 @@ static int map_buffer(cb_handle_t *cb, void **vaddr)
         ALOGE("gralloc: Failed to get host connection\n"); \
         return -EIO; \
     } \
-    renderControl_encoder_context_t *rcEnc = hostCon->rcEncoder(); \
+    ExtendedRCEncoderContext *rcEnc = hostCon->rcEncoder(); \
     if (!rcEnc) { \
         ALOGE("gralloc: Failed to get renderControl encoder context\n"); \
         return -EIO; \
@@ -133,6 +128,72 @@ static int map_buffer(cb_handle_t *cb, void **vaddr)
 #define HAL_PIXEL_FORMAT_YCbCr_420_888 0xFFFFFFFF
 #endif
 
+static void updateHostColorBuffer(cb_handle_t* cb,
+                              bool doLocked,
+                              char* pixels) {
+    D("%s: call. doLocked=%d", __FUNCTION__, doLocked);
+    DEFINE_HOST_CONNECTION;
+    int bpp = glUtilsPixelBitSize(cb->glFormat, cb->glType) >> 3;
+    int left = doLocked ? cb->lockedLeft : 0;
+    int top = doLocked ? cb->lockedTop : 0;
+    int width = doLocked ? cb->lockedWidth : cb->width;
+    int height = doLocked ? cb->lockedHeight : cb->height;
+
+    char* to_send = pixels;
+    uint32_t rgbSz = width * height * bpp;
+    uint32_t send_buffer_size = rgbSz;
+    bool is_rgb_format =
+        cb->frameworkFormat != HAL_PIXEL_FORMAT_YV12 &&
+        cb->frameworkFormat != HAL_PIXEL_FORMAT_YCbCr_420_888;
+
+    char* convertedBuf = NULL;
+    if ((doLocked && is_rgb_format) ||
+        (cb->goldfish_dma.fd < 0 &&
+         (doLocked || !is_rgb_format))) {
+        convertedBuf = new char[rgbSz];
+        to_send = convertedBuf;
+        send_buffer_size = rgbSz;
+    }
+
+    if (doLocked && is_rgb_format) {
+        copy_rgb_buffer(to_send, pixels, width, height, top, left, bpp);
+    }
+
+    if (cb->goldfish_dma.fd > 0) {
+        if (cb->frameworkFormat == HAL_PIXEL_FORMAT_YV12) {
+            get_yv12_offsets(width, height, NULL, NULL,
+                             &send_buffer_size);
+        }
+        if (cb->frameworkFormat == HAL_PIXEL_FORMAT_YCbCr_420_888) {
+            get_yuv420p_offsets(width, height, NULL, NULL,
+                                &send_buffer_size);
+        }
+
+        rcEnc->bindDmaContext(&cb->goldfish_dma);
+        D("%s: call. dma update with sz=%u", __FUNCTION__, send_buffer_size);
+        rcEnc->rcUpdateColorBufferDMA(rcEnc, cb->hostHandle,
+                left, top, width, height,
+                cb->glFormat, cb->glType,
+                to_send, send_buffer_size);
+    } else {
+        if (cb->frameworkFormat == HAL_PIXEL_FORMAT_YV12) {
+            yv12_to_rgb888(to_send, pixels,
+                           width, height, left, top,
+                           left + width - 1, top + height - 1);
+        }
+        if (cb->frameworkFormat == HAL_PIXEL_FORMAT_YCbCr_420_888) {
+            yuv420p_to_rgb888(to_send, pixels,
+                              width, height, left, top,
+                              left + width - 1, top + height - 1);
+        }
+        rcEnc->rcUpdateColorBuffer(rcEnc, cb->hostHandle,
+                left, top, width, height,
+                cb->glFormat, cb->glType, to_send);
+    }
+
+    if (convertedBuf) delete [] convertedBuf;
+}
+
 //
 // gralloc device functions (alloc interface)
 //
@@ -210,6 +271,7 @@ static int gralloc_alloc(alloc_device_t* dev,
 
     GLenum glFormat = 0;
     GLenum glType = 0;
+    EmulatorFrameworkFormat selectedEmuFrameworkFormat = FRAMEWORK_FORMAT_GL_COMPATIBLE;
 
     int bpp = 0;
     int align = 1;
@@ -272,6 +334,7 @@ static int gralloc_alloc(alloc_device_t* dev,
             // We are going to use RGB888 on the host
             glFormat = GL_RGB;
             glType = GL_UNSIGNED_BYTE;
+            selectedEmuFrameworkFormat = FRAMEWORK_FORMAT_YV12;
             break;
         case HAL_PIXEL_FORMAT_YCbCr_420_888:
             ALOGD("%s: 420_888 format experimental path. "
@@ -282,6 +345,7 @@ static int gralloc_alloc(alloc_device_t* dev,
             // We are going to use RGB888 on the host
             glFormat = GL_RGB;
             glType = GL_UNSIGNED_BYTE;
+            selectedEmuFrameworkFormat = FRAMEWORK_FORMAT_YUV_420_888;
             break;
         default:
             ALOGE("gralloc_alloc: Unknown format %d", format);
@@ -320,6 +384,7 @@ static int gralloc_alloc(alloc_device_t* dev,
         // round to page size;
         ashmem_size = (ashmem_size + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1);
 
+        ALOGD("%s: Creating ashmem region of size %lu\n", __FUNCTION__, ashmem_size);
         fd = ashmem_create_region("gralloc-buffer", ashmem_size);
         if (fd < 0) {
             ALOGE("gralloc_alloc failed to create ashmem region: %s\n",
@@ -330,9 +395,11 @@ static int gralloc_alloc(alloc_device_t* dev,
 
     cb_handle_t *cb = new cb_handle_t(fd, ashmem_size, usage,
                                       w, h, frameworkFormat, format,
-                                      glFormat, glType);
+                                      glFormat, glType, selectedEmuFrameworkFormat);
 
+    DEFINE_HOST_CONNECTION;
     if (ashmem_size > 0) {
+
         //
         // map ashmem region if exist
         //
@@ -345,6 +412,22 @@ static int gralloc_alloc(alloc_device_t* dev,
         }
 
         cb->setFd(fd);
+
+        if (rcEnc->getDmaVersion() > 0) {
+            D("%s: creating goldfish dma region of size %lu (cb fd %d)\n", __FUNCTION__, ashmem_size, cb->fd);
+            err = goldfish_dma_create_region(ashmem_size, &cb->goldfish_dma);
+            if (err) {
+                ALOGE("%s: Failed to create goldfish DMA region", __FUNCTION__);
+            } else {
+                goldfish_dma_map(&cb->goldfish_dma);
+                cb->setDmaFd(cb->goldfish_dma.fd);
+                D("%s: done, cbfd %d dmafd1 %d dmafd2 %d", __FUNCTION__, cb->fd, cb->goldfish_dma.fd, cb->dmafd);
+            }
+        } else {
+            cb->goldfish_dma.fd = -1;
+        }
+    } else {
+        cb->goldfish_dma.fd = -1;
     }
 
     //
@@ -367,11 +450,12 @@ static int gralloc_alloc(alloc_device_t* dev,
                      GRALLOC_USAGE_HW_2D |
                      GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_SW_READ_MASK) ) {
 #endif // PLATFORM_SDK_VERSION
-            ALOGD("%s: format %d and usage 0x%x imply creation of host color buffer",
-                  __FUNCTION__, frameworkFormat, usage);
-            DEFINE_HOST_CONNECTION;
             if (hostCon && rcEnc) {
-                cb->hostHandle = rcEnc->rcCreateColorBuffer(rcEnc, w, h, glFormat);
+                if (cb->goldfish_dma.fd > 0) {
+                    cb->hostHandle = rcEnc->rcCreateColorBufferDMA(rcEnc, w, h, glFormat, cb->emuFrameworkFormat);
+                } else {
+                    cb->hostHandle = rcEnc->rcCreateColorBuffer(rcEnc, w, h, glFormat);
+                }
                 D("Created host ColorBuffer 0x%x\n", cb->hostHandle);
             }
 
@@ -414,7 +498,8 @@ static int gralloc_alloc(alloc_device_t* dev,
 static int gralloc_free(alloc_device_t* dev,
                         buffer_handle_t handle)
 {
-    const cb_handle_t *cb = (const cb_handle_t *)handle;
+    D("%s: start", __FUNCTION__);
+    cb_handle_t *cb = (cb_handle_t *)handle;
     if (!cb_handle_t::validate((cb_handle_t*)cb)) {
         ERR("gralloc_free: invalid handle");
         return -EINVAL;
@@ -435,7 +520,17 @@ static int gralloc_free(alloc_device_t* dev,
         }
         close(cb->fd);
     }
+    if (cb->dmafd > 0) {
+        D("%s: unmap and free dma fd %d\n", __FUNCTION__, cb->dmafd);
+        cb->goldfish_dma.fd = cb->dmafd;
+        if (cb->ashmemSize > 0 && cb->ashmemBase) {
+            goldfish_dma_unmap(&cb->goldfish_dma);
+        }
+        goldfish_dma_free(&cb->goldfish_dma);
+        D("%s: closed dma fd %d\n", __FUNCTION__, cb->dmafd);
+    }
 
+    D("%s: done", __FUNCTION__);
     // remove it from the allocated list
     gralloc_device_t *grdev = (gralloc_device_t *)dev;
     pthread_mutex_lock(&grdev->lock);
@@ -461,6 +556,7 @@ static int gralloc_free(alloc_device_t* dev,
 
     delete cb;
 
+    D("%s: exit", __FUNCTION__);
     return 0;
 }
 
@@ -576,6 +672,7 @@ static int fb_close(struct hw_device_t *dev)
 static int gralloc_register_buffer(gralloc_module_t const* module,
                                    buffer_handle_t handle)
 {
+    D("%s: start", __FUNCTION__);
     pthread_once(&sFallbackOnce, fallback_init);
     if (sFallback != NULL) {
         return sFallback->registerBuffer(sFallback, handle);
@@ -608,6 +705,18 @@ static int gralloc_register_buffer(gralloc_module_t const* module,
             return -err;
         }
         cb->mappedPid = getpid();
+        D("%s: checking to map goldfish dma", __FUNCTION__);
+        if (cb->dmafd > 0) {
+            D("%s: attempting to goldfish dma mmap. cbfd %d dmafd1 %d dmafd2 %d", __FUNCTION__, cb->fd, cb->goldfish_dma.fd, cb->dmafd);
+            D("cxt=%p curr pid %d mapped pid %d",
+              &cb->goldfish_dma,
+              (int)getpid(),
+              cb->mappedPid);
+            if (cb->goldfish_dma.fd != cb->dmafd) {
+                cb->goldfish_dma.fd = cb->dmafd;
+            }
+            goldfish_dma_map(&cb->goldfish_dma);
+        }
     }
 
     return 0;
@@ -616,6 +725,7 @@ static int gralloc_register_buffer(gralloc_module_t const* module,
 static int gralloc_unregister_buffer(gralloc_module_t const* module,
                                      buffer_handle_t handle)
 {
+    D("%s: call", __FUNCTION__);
     if (sFallback != NULL) {
         return sFallback->unregisterBuffer(sFallback, handle);
     }
@@ -638,6 +748,7 @@ static int gralloc_unregister_buffer(gralloc_module_t const* module,
     // (through register_buffer)
     //
     if (cb->ashmemSize > 0 && cb->mappedPid == getpid()) {
+        DEFINE_AND_VALIDATE_HOST_CONNECTION;
         void *vaddr;
         int err = munmap((void *)cb->ashmemBase, cb->ashmemSize);
         if (err) {
@@ -646,135 +757,20 @@ static int gralloc_unregister_buffer(gralloc_module_t const* module,
         }
         cb->ashmemBase = 0;
         cb->mappedPid = 0;
+        D("%s: Unregister buffer previous mapped to pid %d", __FUNCTION__, getpid());
+        if (cb->dmafd > 0) {
+            cb->goldfish_dma.fd = cb->dmafd;
+            D("%s: Unmap dma fd %d (%d)", __FUNCTION__, cb->dmafd, cb->goldfish_dma.fd);
+            goldfish_dma_unmap(&cb->goldfish_dma);
+        }
     }
 
-    D("gralloc_unregister_buffer(%p) done\n", cb);
 
-    EXIT_GRALLOCONLY_HOST_CONNECTION;
+    D("gralloc_unregister_buffer(%p) done\n", cb);
     return 0;
 }
 
-static signed clamp_rgb(signed value) {
-    if (value > 255) {
-        value = 255;
-    } else if (value < 0) {
-        value = 0;
-    }
-    return value;
-}
 
-static void rgb565_to_yv12(char* dest, char* src, int width, int height,
-        int left, int top, int right, int bottom) {
-    int align = 16;
-    int yStride = (width + (align -1)) & ~(align-1);
-    int cStride = (yStride / 2 + (align - 1)) & ~(align-1);
-    int yOffset = 0;
-    int cSize = cStride * height/2;
-
-    uint16_t *rgb_ptr0 = (uint16_t *)src;
-    uint8_t *yv12_y0 = (uint8_t *)dest;
-    uint8_t *yv12_v0 = yv12_y0 + yStride * height;
-    uint8_t *yv12_u0 = yv12_v0 + cSize;
-
-    for (int j = top; j <= bottom; ++j) {
-        uint8_t *yv12_y = yv12_y0 + j * yStride;
-        uint8_t *yv12_v = yv12_v0 + (j/2) * cStride;
-        uint8_t *yv12_u = yv12_v + cSize;
-        uint16_t *rgb_ptr = rgb_ptr0 + j * width;
-        bool jeven = (j & 1) == 0;
-        for (int i = left; i <= right; ++i) {
-            uint8_t r = ((rgb_ptr[i]) >> 11) & 0x01f;
-            uint8_t g = ((rgb_ptr[i]) >> 5) & 0x03f;
-            uint8_t b = (rgb_ptr[i]) & 0x01f;
-            // convert to 8bits
-            // http://stackoverflow.com/questions/2442576/how-does-one-convert-16-bit-rgb565-to-24-bit-rgb888
-            uint8_t R = (r * 527 + 23) >> 6;
-            uint8_t G = (g * 259 + 33) >> 6;
-            uint8_t B = (b * 527 + 23) >> 6;
-            // convert to YV12
-            // frameworks/base/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
-            yv12_y[i] = clamp_rgb((77 * R + 150 * G +  29 * B) >> 8);
-            bool ieven = (i & 1) == 0;
-            if (jeven && ieven) {
-                yv12_u[i] = clamp_rgb((( -43 * R - 85 * G + 128 * B) >> 8) + 128);
-                yv12_v[i] = clamp_rgb((( 128 * R - 107 * G - 21 * B) >> 8) + 128);
-            }
-        }
-    }
-}
-
-static void rgb888_to_yv12(char* dest, char* src, int width, int height,
-        int left, int top, int right, int bottom) {
-    DD("%s convert %d by %d", __func__, width, height);
-    int align = 16;
-    int yStride = (width + (align -1)) & ~(align-1);
-    int cStride = (yStride / 2 + (align - 1)) & ~(align-1);
-    int yOffset = 0;
-    int cSize = cStride * height/2;
-    int rgb_stride = 3;
-
-    uint8_t *rgb_ptr0 = (uint8_t *)src;
-    uint8_t *yv12_y0 = (uint8_t *)dest;
-    uint8_t *yv12_v0 = yv12_y0 + yStride * height;
-    uint8_t *yv12_u0 = yv12_v0 + cSize;
-
-    for (int j = top; j <= bottom; ++j) {
-        uint8_t *yv12_y = yv12_y0 + j * yStride;
-        uint8_t *yv12_v = yv12_v0 + (j/2) * cStride;
-        uint8_t *yv12_u = yv12_v + cSize;
-        uint8_t  *rgb_ptr = rgb_ptr0 + j * width*rgb_stride;
-        bool jeven = (j & 1) == 0;
-        for (int i = left; i <= right; ++i) {
-            uint8_t R = rgb_ptr[i*rgb_stride];
-            uint8_t G = rgb_ptr[i*rgb_stride+1];
-            uint8_t B = rgb_ptr[i*rgb_stride+2];
-            // convert to YV12
-            // frameworks/base/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
-            yv12_y[i] = clamp_rgb((77 * R + 150 * G +  29 * B) >> 8);
-            bool ieven = (i & 1) == 0;
-            if (jeven && ieven) {
-                yv12_u[i] = clamp_rgb((( -43 * R - 85 * G + 128 * B) >> 8) + 128);
-                yv12_v[i] = clamp_rgb((( 128 * R - 107 * G - 21 * B) >> 8) + 128);
-            }
-        }
-    }
-}
-
-static void rgb888_to_yuv420p(char* dest, char* src, int width, int height,
-        int left, int top, int right, int bottom) {
-    DD("%s convert %d by %d", __func__, width, height);
-    int yStride = width;
-    int cStride = yStride / 2;
-    int yOffset = 0;
-    int cSize = cStride * height/2;
-    int rgb_stride = 3;
-
-    uint8_t *rgb_ptr0 = (uint8_t *)src;
-    uint8_t *yv12_y0 = (uint8_t *)dest;
-    uint8_t *yv12_u0 = yv12_y0 + yStride * height;
-    uint8_t *yv12_v0 = yv12_u0 + cSize;
-
-    for (int j = top; j <= bottom; ++j) {
-        uint8_t *yv12_y = yv12_y0 + j * yStride;
-        uint8_t *yv12_u = yv12_u0 + (j/2) * cStride;
-        uint8_t *yv12_v = yv12_u + cStride;
-        uint8_t  *rgb_ptr = rgb_ptr0 + j * width*rgb_stride;
-        bool jeven = (j & 1) == 0;
-        for (int i = left; i <= right; ++i) {
-            uint8_t R = rgb_ptr[i*rgb_stride];
-            uint8_t G = rgb_ptr[i*rgb_stride+1];
-            uint8_t B = rgb_ptr[i*rgb_stride+2];
-            // convert to YV12
-            // frameworks/base/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
-            yv12_y[i] = clamp_rgb((77 * R + 150 * G +  29 * B) >> 8);
-            bool ieven = (i & 1) == 0;
-            if (jeven && ieven) {
-                yv12_u[i] = clamp_rgb((( -43 * R - 85 * G + 128 * B) >> 8) + 128);
-                yv12_v[i] = clamp_rgb((( 128 * R - 107 * G - 21 * B) >> 8) + 128);
-            }
-        }
-    }
-}
 
 static int gralloc_lock(gralloc_module_t const* module,
                         buffer_handle_t handle, int usage,
@@ -925,142 +921,6 @@ static int gralloc_lock(gralloc_module_t const* module,
     return 0;
 }
 
-// YV12 is aka YUV420Planar, or YUV420p; the only difference is that YV12 has
-// certain stride requirements for Y and UV respectively.
-static void yv12_to_rgb565(char* dest, char* src, int width, int height,
-        int left, int top, int right, int bottom) {
-    DD("%s convert %d by %d", __func__, width, height);
-    int align = 16;
-    int yStride = (width + (align -1)) & ~(align-1);
-    int cStride = (yStride / 2 + (align - 1)) & ~(align-1);
-    int yOffset = 0;
-    int cSize = cStride * height/2;
-
-    uint16_t *rgb_ptr0 = (uint16_t *)dest;
-    uint8_t *yv12_y0 = (uint8_t *)src;
-    uint8_t *yv12_v0 = yv12_y0 + yStride * height;
-    uint8_t *yv12_u0 = yv12_v0 + cSize;
-
-    for (int j = top; j <= bottom; ++j) {
-        uint8_t *yv12_y = yv12_y0 + j * yStride;
-        uint8_t *yv12_v = yv12_v0 + (j/2) * cStride;
-        uint8_t *yv12_u = yv12_v + cSize;
-        uint16_t *rgb_ptr = rgb_ptr0 + (j-top) * (right-left+1);
-        for (int i = left; i <= right; ++i) {
-            // convert to rgb
-            // frameworks/av/media/libstagefright/colorconversion/ColorConverter.cpp
-            signed y1 = (signed)yv12_y[i] - 16;
-            signed u = (signed)yv12_u[i / 2] - 128;
-            signed v = (signed)yv12_v[i / 2] - 128;
-
-            signed u_b = u * 517;
-            signed u_g = -u * 100;
-            signed v_g = -v * 208;
-            signed v_r = v * 409;
-
-            signed tmp1 = y1 * 298;
-            signed b1 = clamp_rgb((tmp1 + u_b) / 256);
-            signed g1 = clamp_rgb((tmp1 + v_g + u_g) / 256);
-            signed r1 = clamp_rgb((tmp1 + v_r) / 256);
-
-            uint16_t rgb1 = ((r1 >> 3) << 11) | ((g1 >> 2) << 5) | (b1 >> 3);
-
-            rgb_ptr[i-left] = rgb1;
-        }
-    }
-}
-
-// YV12 is aka YUV420Planar, or YUV420p; the only difference is that YV12 has
-// certain stride requirements for Y and UV respectively.
-static void yv12_to_rgb888(char* dest, char* src, int width, int height,
-        int left, int top, int right, int bottom) {
-    DD("%s convert %d by %d", __func__, width, height);
-    int align = 16;
-    int yStride = (width + (align -1)) & ~(align-1);
-    int cStride = (yStride / 2 + (align - 1)) & ~(align-1);
-    int yOffset = 0;
-    int cSize = cStride * height/2;
-    int rgb_stride = 3;
-
-    uint8_t *rgb_ptr0 = (uint8_t *)dest;
-    uint8_t *yv12_y0 = (uint8_t *)src;
-    uint8_t *yv12_v0 = yv12_y0 + yStride * height;
-    uint8_t *yv12_u0 = yv12_v0 + cSize;
-
-    for (int j = top; j <= bottom; ++j) {
-        uint8_t *yv12_y = yv12_y0 + j * yStride;
-        uint8_t *yv12_v = yv12_v0 + (j/2) * cStride;
-        uint8_t *yv12_u = yv12_v + cSize;
-        uint8_t *rgb_ptr = rgb_ptr0 + (j-top) * (right-left+1) * rgb_stride;
-        for (int i = left; i <= right; ++i) {
-            // convert to rgb
-            // frameworks/av/media/libstagefright/colorconversion/ColorConverter.cpp
-            signed y1 = (signed)yv12_y[i] - 16;
-            signed u = (signed)yv12_u[i / 2] - 128;
-            signed v = (signed)yv12_v[i / 2] - 128;
-
-            signed u_b = u * 517;
-            signed u_g = -u * 100;
-            signed v_g = -v * 208;
-            signed v_r = v * 409;
-
-            signed tmp1 = y1 * 298;
-            signed b1 = clamp_rgb((tmp1 + u_b) / 256);
-            signed g1 = clamp_rgb((tmp1 + v_g + u_g) / 256);
-            signed r1 = clamp_rgb((tmp1 + v_r) / 256);
-
-            rgb_ptr[(i-left)*rgb_stride] = r1;
-            rgb_ptr[(i-left)*rgb_stride+1] = g1;
-            rgb_ptr[(i-left)*rgb_stride+2] = b1;
-        }
-    }
-}
-
-// YV12 is aka YUV420Planar, or YUV420p; the only difference is that YV12 has
-// certain stride requirements for Y and UV respectively.
-static void yuv420p_to_rgb888(char* dest, char* src, int width, int height,
-        int left, int top, int right, int bottom) {
-    DD("%s convert %d by %d", __func__, width, height);
-    int yStride = width;
-    int cStride = yStride / 2;
-    int yOffset = 0;
-    int cSize = cStride * height/2;
-    int rgb_stride = 3;
-
-    uint8_t *rgb_ptr0 = (uint8_t *)dest;
-    uint8_t *yv12_y0 = (uint8_t *)src;
-    uint8_t *yv12_u0 = yv12_y0 + yStride * height;
-    uint8_t *yv12_v0 = yv12_u0 + cSize;
-
-    for (int j = top; j <= bottom; ++j) {
-        uint8_t *yv12_y = yv12_y0 + j * yStride;
-        uint8_t *yv12_u = yv12_u0 + (j/2) * cStride;
-        uint8_t *yv12_v = yv12_u + cSize;
-        uint8_t *rgb_ptr = rgb_ptr0 + (j-top) * (right-left+1) * rgb_stride;
-        for (int i = left; i <= right; ++i) {
-            // convert to rgb
-            // frameworks/av/media/libstagefright/colorconversion/ColorConverter.cpp
-            signed y1 = (signed)yv12_y[i] - 16;
-            signed u = (signed)yv12_u[i / 2] - 128;
-            signed v = (signed)yv12_v[i / 2] - 128;
-
-            signed u_b = u * 517;
-            signed u_g = -u * 100;
-            signed v_g = -v * 208;
-            signed v_r = v * 409;
-
-            signed tmp1 = y1 * 298;
-            signed b1 = clamp_rgb((tmp1 + u_b) / 256);
-            signed g1 = clamp_rgb((tmp1 + v_g + u_g) / 256);
-            signed r1 = clamp_rgb((tmp1 + v_r) / 256);
-
-            rgb_ptr[(i-left)*rgb_stride] = r1;
-            rgb_ptr[(i-left)*rgb_stride+1] = g1;
-            rgb_ptr[(i-left)*rgb_stride+2] = b1;
-        }
-    }
-}
-
 static int gralloc_unlock(gralloc_module_t const* module,
                           buffer_handle_t handle)
 {
@@ -1094,57 +954,10 @@ static int gralloc_unlock(gralloc_module_t const* module,
 
         char* rgb_addr = (char *)cpu_addr;
         if (cb->lockedWidth < cb->width || cb->lockedHeight < cb->height) {
-            int bpp = glUtilsPixelBitSize(cb->glFormat, cb->glType) >> 3;
-            char *tmpBuf = new char[cb->lockedWidth * cb->lockedHeight * bpp];
-            if (cb->frameworkFormat == HAL_PIXEL_FORMAT_YV12) {
-                yv12_to_rgb888(tmpBuf, (char*)cpu_addr, cb->width, cb->height, cb->lockedLeft,
-                               cb->lockedTop, cb->lockedLeft+cb->lockedWidth-1, cb->lockedTop+cb->lockedHeight-1);
-            } else if (cb->frameworkFormat == HAL_PIXEL_FORMAT_YCbCr_420_888) {
-                yuv420p_to_rgb888(tmpBuf, (char*)cpu_addr, cb->width, cb->height, cb->lockedLeft,
-                               cb->lockedTop, cb->lockedLeft+cb->lockedWidth-1, cb->lockedTop+cb->lockedHeight-1);
-            } else {
-                int dst_line_len = cb->lockedWidth * bpp;
-                int src_line_len = cb->width * bpp;
-                char *src = (char *)rgb_addr + cb->lockedTop*src_line_len + cb->lockedLeft*bpp;
-                char *dst = tmpBuf;
-                for (int y=0; y<cb->lockedHeight; y++) {
-                    memcpy(dst, src, dst_line_len);
-                    src += src_line_len;
-                    dst += dst_line_len;
-                }
-            }
-
-            rcEnc->rcUpdateColorBuffer(rcEnc, cb->hostHandle,
-                                       cb->lockedLeft, cb->lockedTop,
-                                       cb->lockedWidth, cb->lockedHeight,
-                                       cb->glFormat, cb->glType,
-                                       tmpBuf);
-
-            delete [] tmpBuf;
+            updateHostColorBuffer(cb, true, rgb_addr);
         }
         else {
-            char* rgbBuf = 0;
-            if (cb->frameworkFormat == HAL_PIXEL_FORMAT_YV12) {
-                // for this format, we need to convert to RGB888 format
-                // before updating host
-                rgbBuf = new char[cb->width * cb->height * 3];
-                yv12_to_rgb888(rgbBuf, (char*)cpu_addr, cb->width, cb->height, 0, 0, cb->width-1, cb->height-1);
-                rgb_addr = rgbBuf;
-            } else if (cb->frameworkFormat == HAL_PIXEL_FORMAT_YCbCr_420_888) {
-                // for this format, we need to convert to RGB888 format
-                // before updating host
-                rgbBuf = new char[cb->width * cb->height * 3];
-                yuv420p_to_rgb888(rgbBuf, (char*)cpu_addr, cb->width, cb->height, 0, 0, cb->width-1, cb->height-1);
-                rgb_addr = rgbBuf;
-            }
-
-            rcEnc->rcUpdateColorBuffer(rcEnc, cb->hostHandle, 0, 0,
-                                       cb->width, cb->height,
-                                       cb->glFormat, cb->glType,
-                                       rgb_addr);
-            if (rgbBuf) {
-                delete [] rgbBuf;
-            }
+            updateHostColorBuffer(cb, false, rgb_addr);
         }
 
         DD("gralloc_unlock success. cpu_addr: %p", cpu_addr);
index a97f305..617e8f9 100644 (file)
@@ -44,6 +44,8 @@ int renderControl_client_context_t::initDispatchByName(void *(*getProc)(const ch
        rcFlushWindowColorBufferAsync = (rcFlushWindowColorBufferAsync_client_proc_t) getProc("rcFlushWindowColorBufferAsync", userData);
        rcDestroySyncKHR = (rcDestroySyncKHR_client_proc_t) getProc("rcDestroySyncKHR", userData);
        rcSetPuid = (rcSetPuid_client_proc_t) getProc("rcSetPuid", userData);
+       rcUpdateColorBufferDMA = (rcUpdateColorBufferDMA_client_proc_t) getProc("rcUpdateColorBufferDMA", userData);
+       rcCreateColorBufferDMA = (rcCreateColorBufferDMA_client_proc_t) getProc("rcCreateColorBufferDMA", userData);
        return 0;
 }
 
index fa121ea..7a3e3f6 100644 (file)
@@ -44,6 +44,8 @@ struct renderControl_client_context_t {
        rcFlushWindowColorBufferAsync_client_proc_t rcFlushWindowColorBufferAsync;
        rcDestroySyncKHR_client_proc_t rcDestroySyncKHR;
        rcSetPuid_client_proc_t rcSetPuid;
+       rcUpdateColorBufferDMA_client_proc_t rcUpdateColorBufferDMA;
+       rcCreateColorBufferDMA_client_proc_t rcCreateColorBufferDMA;
        virtual ~renderControl_client_context_t() {}
 
        typedef renderControl_client_context_t *CONTEXT_ACCESSOR_TYPE(void);
index cfde952..e517d07 100644 (file)
@@ -43,6 +43,8 @@ typedef EGLint (renderControl_APIENTRY *rcClientWaitSyncKHR_client_proc_t) (void
 typedef void (renderControl_APIENTRY *rcFlushWindowColorBufferAsync_client_proc_t) (void * ctx, uint32_t);
 typedef int (renderControl_APIENTRY *rcDestroySyncKHR_client_proc_t) (void * ctx, uint64_t);
 typedef void (renderControl_APIENTRY *rcSetPuid_client_proc_t) (void * ctx, uint64_t);
+typedef int (renderControl_APIENTRY *rcUpdateColorBufferDMA_client_proc_t) (void * ctx, uint32_t, GLint, GLint, GLint, GLint, GLenum, GLenum, void*, uint32_t);
+typedef uint32_t (renderControl_APIENTRY *rcCreateColorBufferDMA_client_proc_t) (void * ctx, uint32_t, uint32_t, GLenum, int);
 
 
 #endif
index 6883117..3c4a3f3 100644 (file)
@@ -1273,6 +1273,98 @@ void rcSetPuid_enc(void *self , uint64_t puid)
 
 }
 
+int rcUpdateColorBufferDMA_enc(void *self , uint32_t colorbuffer, GLint x, GLint y, GLint width, GLint height, GLenum format, GLenum type, void* pixels, uint32_t pixels_size)
+{
+
+       renderControl_encoder_context_t *ctx = (renderControl_encoder_context_t *)self;
+       IOStream *stream = ctx->m_stream;
+       ChecksumCalculator *checksumCalculator = ctx->m_checksumCalculator;
+       bool useChecksum = checksumCalculator->getVersion() > 0;
+
+       const unsigned int __size_pixels =  pixels_size;
+        unsigned char *ptr;
+        unsigned char *buf;
+        const size_t sizeWithoutChecksum = 8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 8 + 4 + 1*4;
+        const size_t checksumSize = checksumCalculator->checksumByteSize();
+        const size_t totalSize = sizeWithoutChecksum + checksumSize;
+       buf = stream->alloc(totalSize);
+       ptr = buf;
+       int tmp = OP_rcUpdateColorBufferDMA;memcpy(ptr, &tmp, 4); ptr += 4;
+       memcpy(ptr, &totalSize, 4);  ptr += 4;
+
+               memcpy(ptr, &colorbuffer, 4); ptr += 4;
+               memcpy(ptr, &x, 4); ptr += 4;
+               memcpy(ptr, &y, 4); ptr += 4;
+               memcpy(ptr, &width, 4); ptr += 4;
+               memcpy(ptr, &height, 4); ptr += 4;
+               memcpy(ptr, &format, 4); ptr += 4;
+               memcpy(ptr, &type, 4); ptr += 4;
+       *(uint64_t *)(ptr) = ctx->lockAndWriteDma(pixels, __size_pixels); ptr += 8;
+               memcpy(ptr, &pixels_size, 4); ptr += 4;
+
+       if (useChecksum) checksumCalculator->addBuffer(buf, ptr-buf);
+       if (useChecksum) checksumCalculator->writeChecksum(ptr, checksumSize); ptr += checksumSize;
+
+
+       int retval;
+       stream->readback(&retval, 4);
+       if (useChecksum) checksumCalculator->addBuffer(&retval, 4);
+       if (useChecksum) {
+               unsigned char *checksumBufPtr = NULL;
+               unsigned char checksumBuf[ChecksumCalculator::kMaxChecksumSize];
+               if (checksumSize > 0) checksumBufPtr = &checksumBuf[0];
+               stream->readback(checksumBufPtr, checksumSize);
+               if (!checksumCalculator->validate(checksumBufPtr, checksumSize)) {
+                       ALOGE("rcUpdateColorBufferDMA: GL communication error, please report this issue to b.android.com.\n");
+                       abort();
+               }
+       }
+       return retval;
+}
+
+uint32_t rcCreateColorBufferDMA_enc(void *self , uint32_t width, uint32_t height, GLenum internalFormat, int frameworkFormat)
+{
+
+       renderControl_encoder_context_t *ctx = (renderControl_encoder_context_t *)self;
+       IOStream *stream = ctx->m_stream;
+       ChecksumCalculator *checksumCalculator = ctx->m_checksumCalculator;
+       bool useChecksum = checksumCalculator->getVersion() > 0;
+
+        unsigned char *ptr;
+        unsigned char *buf;
+        const size_t sizeWithoutChecksum = 8 + 4 + 4 + 4 + 4;
+        const size_t checksumSize = checksumCalculator->checksumByteSize();
+        const size_t totalSize = sizeWithoutChecksum + checksumSize;
+       buf = stream->alloc(totalSize);
+       ptr = buf;
+       int tmp = OP_rcCreateColorBufferDMA;memcpy(ptr, &tmp, 4); ptr += 4;
+       memcpy(ptr, &totalSize, 4);  ptr += 4;
+
+               memcpy(ptr, &width, 4); ptr += 4;
+               memcpy(ptr, &height, 4); ptr += 4;
+               memcpy(ptr, &internalFormat, 4); ptr += 4;
+               memcpy(ptr, &frameworkFormat, 4); ptr += 4;
+
+       if (useChecksum) checksumCalculator->addBuffer(buf, ptr-buf);
+       if (useChecksum) checksumCalculator->writeChecksum(ptr, checksumSize); ptr += checksumSize;
+
+
+       uint32_t retval;
+       stream->readback(&retval, 4);
+       if (useChecksum) checksumCalculator->addBuffer(&retval, 4);
+       if (useChecksum) {
+               unsigned char *checksumBufPtr = NULL;
+               unsigned char checksumBuf[ChecksumCalculator::kMaxChecksumSize];
+               if (checksumSize > 0) checksumBufPtr = &checksumBuf[0];
+               stream->readback(checksumBufPtr, checksumSize);
+               if (!checksumCalculator->validate(checksumBufPtr, checksumSize)) {
+                       ALOGE("rcCreateColorBufferDMA: GL communication error, please report this issue to b.android.com.\n");
+                       abort();
+               }
+       }
+       return retval;
+}
+
 }  // namespace
 
 renderControl_encoder_context_t::renderControl_encoder_context_t(IOStream *stream, ChecksumCalculator *checksumCalculator)
@@ -1314,5 +1406,7 @@ renderControl_encoder_context_t::renderControl_encoder_context_t(IOStream *strea
        this->rcFlushWindowColorBufferAsync = &rcFlushWindowColorBufferAsync_enc;
        this->rcDestroySyncKHR = &rcDestroySyncKHR_enc;
        this->rcSetPuid = &rcSetPuid_enc;
+       this->rcUpdateColorBufferDMA = &rcUpdateColorBufferDMA_enc;
+       this->rcCreateColorBufferDMA = &rcCreateColorBufferDMA_enc;
 }
 
index 628cff3..7db4964 100644 (file)
@@ -19,6 +19,7 @@ struct renderControl_encoder_context_t : public renderControl_client_context_t {
        ChecksumCalculator *m_checksumCalculator;
 
        renderControl_encoder_context_t(IOStream *stream, ChecksumCalculator *checksumCalculator);
+       virtual uint64_t lockAndWriteDma(void* data, uint32_t sz) { return 0; }
 };
 
 #endif  // GUARD_renderControl_encoder_context_t
\ No newline at end of file
index 8ff4d6a..d33cf05 100644 (file)
@@ -40,6 +40,8 @@ extern "C" {
        void rcFlushWindowColorBufferAsync(uint32_t windowSurface);
        int rcDestroySyncKHR(uint64_t sync);
        void rcSetPuid(uint64_t puid);
+       int rcUpdateColorBufferDMA(uint32_t colorbuffer, GLint x, GLint y, GLint width, GLint height, GLenum format, GLenum type, void* pixels, uint32_t pixels_size);
+       uint32_t rcCreateColorBufferDMA(uint32_t width, uint32_t height, GLenum internalFormat, int frameworkFormat);
 };
 
 #endif
@@ -253,3 +255,15 @@ void rcSetPuid(uint64_t puid)
        ctx->rcSetPuid(ctx, puid);
 }
 
+int rcUpdateColorBufferDMA(uint32_t colorbuffer, GLint x, GLint y, GLint width, GLint height, GLenum format, GLenum type, void* pixels, uint32_t pixels_size)
+{
+       GET_CONTEXT;
+       return ctx->rcUpdateColorBufferDMA(ctx, colorbuffer, x, y, width, height, format, type, pixels, pixels_size);
+}
+
+uint32_t rcCreateColorBufferDMA(uint32_t width, uint32_t height, GLenum internalFormat, int frameworkFormat)
+{
+       GET_CONTEXT;
+       return ctx->rcCreateColorBufferDMA(ctx, width, height, internalFormat, frameworkFormat);
+}
+
index eaee76a..4f2a09e 100644 (file)
@@ -42,6 +42,8 @@ static const struct _renderControl_funcs_by_name {
        {"rcFlushWindowColorBufferAsync", (void*)rcFlushWindowColorBufferAsync},
        {"rcDestroySyncKHR", (void*)rcDestroySyncKHR},
        {"rcSetPuid", (void*)rcSetPuid},
+       {"rcUpdateColorBufferDMA", (void*)rcUpdateColorBufferDMA},
+       {"rcCreateColorBufferDMA", (void*)rcCreateColorBufferDMA},
 };
 static const int renderControl_num_funcs = sizeof(renderControl_funcs_by_name) / sizeof(struct _renderControl_funcs_by_name);
 
index 5112a6a..43d8f30 100644 (file)
@@ -37,7 +37,9 @@
 #define OP_rcFlushWindowColorBufferAsync                                       10031
 #define OP_rcDestroySyncKHR                                    10032
 #define OP_rcSetPuid                                   10033
-#define OP_last                                        10034
+#define OP_rcUpdateColorBufferDMA                                      10034
+#define OP_rcCreateColorBufferDMA                                      10035
+#define OP_last                                        10036
 
 
 #endif