Hash :
bbf67e2e
Author :
Date :
2022-05-16T12:04:34
Capture/Replay: support capturing eglCreateImage/eglDestroyImage Because we support only a few functions the supporting code is not autogenerated. We don't capture the actual value of the display variable, because we assume that there is only one display, and the actual pointer to it is provided by the EGLWindow. The rest of the capturing works just like with the GLES calls. Bug: angleproject:4964 Bug: angleproject:5822 Bug: angleproject:6180 Bug: angleproject:6286 Bug: angleproject:6578 Bug: angleproject:7111 Change-Id: I385aa9648f93bf74706e9860e2aee5775eeba220 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3636062 Reviewed-by: Jamie Madill <jmadill@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: Cody Northrop <cnorthrop@google.com>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
//
// Copyright 2022 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// capture_egl.h:
// EGL capture functions
//
#include "libANGLE/capture/capture_egl.h"
#include "libANGLE/capture/FrameCapture.h"
#include "libANGLE/capture/frame_capture_utils.h"
#include "libANGLE/capture/gl_enum_utils_autogen.h"
#define USE_SYSTEM_ZLIB
#include "compression_utils_portable.h"
#if !ANGLE_CAPTURE_ENABLED
# error Frame capture must be enabled to include this file.
#endif // !ANGLE_CAPTURE_ENABLED
namespace angle
{
template <>
void WriteParamValueReplay<ParamType::TEGLContext>(std::ostream &os,
const CallCapture &call,
EGLContext value)
{
// We actually capture the context ID
uint64_t contextID = reinterpret_cast<uint64_t>(value);
// The context map uses uint32_t as key type
ASSERT(contextID <= 0xffffffffull);
os << "static_cast<EGLContext>(gContextMap[" << contextID << "])";
}
template <>
void WriteParamValueReplay<ParamType::TEGLDisplay>(std::ostream &os,
const CallCapture &call,
EGLDisplay value)
{
ASSERT(value == EGL_NO_DISPLAY);
os << "EGL_NO_DISPLAY";
}
template <>
void WriteParamValueReplay<ParamType::TEGLSurface>(std::ostream &os,
const CallCapture &call,
EGLSurface value)
{
if (value == EGL_NO_SURFACE)
{
os << "EGL_NO_SURFACE";
return;
}
// We don't support capturing this EGL call
UNREACHABLE();
}
template <>
void WriteParamValueReplay<ParamType::TEGLClientBuffer>(std::ostream &os,
const CallCapture &call,
EGLClientBuffer value)
{
const auto &targetParam = call.params.getParam("target", ParamType::TEGLenum, 2);
os << "GetClientBuffer(" << targetParam.value.EGLenumVal << ", " << value << ")";
}
} // namespace angle
namespace egl
{
static angle::ParamCapture CaptureAttributeMap(const egl::AttributeMap &attribMap)
{
std::vector<EGLAttrib> attribs;
for (const auto &[key, value] : attribMap)
{
attribs.push_back(key);
attribs.push_back(value);
}
attribs.push_back(EGL_NONE);
angle::ParamCapture paramCapture("attrib_list", angle::ParamType::TGLint64Pointer);
angle::CaptureMemory(attribs.data(), attribs.size() * sizeof(EGLAttrib), ¶mCapture);
return paramCapture;
}
angle::CallCapture CaptureCreateNativeClientBufferANDROID(gl::Context *context,
const egl::AttributeMap &attribMap,
EGLClientBuffer eglClientBuffer)
{
angle::ParamBuffer paramBuffer;
paramBuffer.addParam(CaptureAttributeMap(attribMap));
angle::ParamCapture retval;
angle::SetParamVal<angle::ParamType::TEGLClientBuffer, EGLClientBuffer>(eglClientBuffer,
&retval.value);
paramBuffer.addReturnValue(std::move(retval));
return angle::CallCapture(angle::EntryPoint::EGLCreateNativeClientBufferANDROID,
std::move(paramBuffer));
}
angle::CallCapture CaptureEGLCreateImage(gl::Context *context,
EGLenum target,
EGLClientBuffer buffer,
const egl::AttributeMap &attributes,
egl::Image *image)
{
angle::ParamBuffer paramBuffer;
// The EGL display will be queried directly in the emitted code
// so this is actually just a place holder
paramBuffer.addValueParam("display", angle::ParamType::TEGLContext, EGL_NO_DISPLAY);
// In CaptureMidExecutionSetup and FrameCaptureShared::captureCall
// we capture the actual context ID (via CaptureMakeCurrent),
// so we have to do the same here.
uint64_t contextID = context->id().value;
EGLContext eglContext = reinterpret_cast<EGLContext>(contextID);
paramBuffer.addValueParam("context", angle::ParamType::TEGLContext, eglContext);
paramBuffer.addEnumParam("target", gl::GLenumGroup::DefaultGroup, angle::ParamType::TEGLenum,
target);
angle::ParamCapture paramsClientBuffer("buffer", angle::ParamType::TEGLClientBuffer);
uint64_t bufferID = reinterpret_cast<uintptr_t>(buffer);
angle::SetParamVal<angle::ParamType::TGLuint64>(bufferID, ¶msClientBuffer.value);
paramBuffer.addParam(std::move(paramsClientBuffer));
angle::ParamCapture paramsAttr = CaptureAttributeMap(attributes);
paramBuffer.addParam(std::move(paramsAttr));
angle::ParamCapture retval;
angle::SetParamVal<angle::ParamType::TGLeglImageOES, GLeglImageOES>(image, &retval.value);
paramBuffer.addReturnValue(std::move(retval));
return angle::CallCapture(angle::EntryPoint::EGLCreateImage, std::move(paramBuffer));
}
angle::CallCapture CaptureEGLDestroyImage(gl::Context *context,
egl::Display *display,
egl::Image *image)
{
angle::ParamBuffer paramBuffer;
paramBuffer.addValueParam("display", angle::ParamType::TEGLContext, EGL_NO_DISPLAY);
angle::ParamCapture paramImage("image", angle::ParamType::TGLeglImageOES);
angle::SetParamVal<angle::ParamType::TGLeglImageOES, GLeglImageOES>(image, ¶mImage.value);
paramBuffer.addParam(std::move(paramImage));
return angle::CallCapture(angle::EntryPoint::EGLDestroyImage, std::move(paramBuffer));
}
} // namespace egl