Merge "Fix windows build." into studio-1.4-dev
diff --git a/cc/gapic/coder/gles.h b/cc/gapic/coder/gles.h
index d45598e..647cccc 100644
--- a/cc/gapic/coder/gles.h
+++ b/cc/gapic/coder/gles.h
@@ -45,16 +45,17 @@
class BackbufferInfo: public Encodable {
public:
BackbufferInfo() = default;
- BackbufferInfo(atom::Observations observations, int32_t Width, int32_t Height, uint32_t ColorFmt, uint32_t DepthFmt, uint32_t StencilFmt, bool ResetViewportScissor) :
+ BackbufferInfo(atom::Observations observations, int32_t Width, int32_t Height, uint32_t ColorFmt, uint32_t DepthFmt, uint32_t StencilFmt, bool ResetViewportScissor, bool PreserveBuffersOnSwap) :
mobservations(observations),
mWidth(Width),
mHeight(Height),
mColorFmt(ColorFmt),
mDepthFmt(DepthFmt),
mStencilFmt(StencilFmt),
- mResetViewportScissor(ResetViewportScissor) {}
+ mResetViewportScissor(ResetViewportScissor),
+ mPreserveBuffersOnSwap(PreserveBuffersOnSwap) {}
virtual const gapic::Id& Id() const {
- static gapic::Id ID{ { 0x18, 0x3c, 0x07, 0xe1, 0x0c, 0x71, 0x64, 0xee, 0xaa, 0x70, 0x7a, 0xb3, 0xca, 0xbe, 0x36, 0x00, 0xe8, 0xeb, 0x8c, 0xed, } };
+ static gapic::Id ID{ { 0x3b, 0x71, 0x56, 0x1e, 0xbc, 0xdf, 0xd7, 0x44, 0xcf, 0x32, 0xc5, 0x65, 0xe5, 0x66, 0xf0, 0x8f, 0x1b, 0x28, 0x23, 0xa7, } };
return ID;
}
virtual void Encode(Encoder* e) const {
@@ -65,6 +66,7 @@
e->Uint32(this->mDepthFmt);
e->Uint32(this->mStencilFmt);
e->Bool(this->mResetViewportScissor);
+ e->Bool(this->mPreserveBuffersOnSwap);
}
atom::Observations mobservations;
@@ -74,6 +76,7 @@
uint32_t mDepthFmt;
uint32_t mStencilFmt;
bool mResetViewportScissor;
+ bool mPreserveBuffersOnSwap;
};
class Color: public Encodable {
@@ -1283,7 +1286,7 @@
class Context: public Encodable {
public:
Context() = default;
- Context(uint64_t CreatedAt, uint32_t Identifier, BlendState Blending, RasterizerState Rasterizing, ClearState Clearing, std::unordered_map<uint32_t,uint32_t>* BoundFramebuffers, std::unordered_map<uint32_t,uint32_t>* BoundRenderbuffers, std::unordered_map<uint32_t,uint32_t>* BoundBuffers, uint32_t BoundProgram, uint32_t BoundVertexArray, std::unordered_map<int32_t,VertexAttributeArray*>* VertexAttributeArrays, std::unordered_map<uint32_t,std::unordered_map<uint32_t,uint32_t>*>* TextureUnits, uint32_t ActiveTextureUnit, std::unordered_map<uint32_t,bool>* Capabilities, uint32_t GenerateMipmapHint, std::unordered_map<uint32_t,int32_t>* PixelStorage, Objects Instances) :
+ Context(uint64_t CreatedAt, uint32_t Identifier, BlendState Blending, RasterizerState Rasterizing, ClearState Clearing, std::unordered_map<uint32_t,uint32_t>* BoundFramebuffers, std::unordered_map<uint32_t,uint32_t>* BoundRenderbuffers, std::unordered_map<uint32_t,uint32_t>* BoundBuffers, uint32_t BoundProgram, uint32_t BoundVertexArray, std::unordered_map<int32_t,VertexAttributeArray*>* VertexAttributeArrays, std::unordered_map<uint32_t,std::unordered_map<uint32_t,uint32_t>*>* TextureUnits, uint32_t ActiveTextureUnit, std::unordered_map<uint32_t,bool>* Capabilities, uint32_t GenerateMipmapHint, std::unordered_map<uint32_t,int32_t>* PixelStorage, Objects Instances, bool PreserveBuffersOnSwap) :
mCreatedAt(CreatedAt),
mIdentifier(Identifier),
mBlending(Blending),
@@ -1300,9 +1303,10 @@
mCapabilities(Capabilities),
mGenerateMipmapHint(GenerateMipmapHint),
mPixelStorage(PixelStorage),
- mInstances(Instances) {}
+ mInstances(Instances),
+ mPreserveBuffersOnSwap(PreserveBuffersOnSwap) {}
virtual const gapic::Id& Id() const {
- static gapic::Id ID{ { 0x5d, 0x15, 0x38, 0x06, 0x50, 0x11, 0xdd, 0x3b, 0xf6, 0x52, 0x52, 0xca, 0xc5, 0x29, 0x63, 0xdc, 0xe5, 0x1d, 0x52, 0x4a, } };
+ static gapic::Id ID{ { 0x2d, 0x31, 0xd7, 0x8d, 0xe9, 0x76, 0xe7, 0x8c, 0xd4, 0xda, 0x77, 0xca, 0x1b, 0x5f, 0x8a, 0xc3, 0xa9, 0x35, 0xb2, 0x2c, } };
return ID;
}
virtual void Encode(Encoder* e) const {
@@ -1323,6 +1327,7 @@
e->Uint32(this->mGenerateMipmapHint);
GAPID_FATAL("C++ map encoding not supported");
e->Value(this->mInstances);
+ e->Bool(this->mPreserveBuffersOnSwap);
}
uint64_t mCreatedAt;
@@ -1342,6 +1347,7 @@
uint32_t mGenerateMipmapHint;
std::unordered_map<uint32_t,int32_t>* mPixelStorage;
Objects mInstances;
+ bool mPreserveBuffersOnSwap;
};
class EGLConfig: public Encodable {
diff --git a/cc/gapii/gles_spy.h b/cc/gapii/gles_spy.h
index 0c3570b..47882dc 100644
--- a/cc/gapii/gles_spy.h
+++ b/cc/gapii/gles_spy.h
@@ -322,7 +322,8 @@
inline void replayBindRenderer(uint32_t id);
inline void switchThread(uint64_t threadID);
inline void backbufferInfo(int32_t width, int32_t height, uint32_t color_fmt,
- uint32_t depth_fmt, uint32_t stencil_fmt, bool resetViewportScissor);
+ uint32_t depth_fmt, uint32_t stencil_fmt, bool resetViewportScissor,
+ bool preserveBuffersOnSwap);
inline void startTimer(uint8_t index);
inline uint64_t stopTimer(uint8_t index);
inline void flushPostBuffer();
@@ -6207,15 +6208,16 @@
inline void GlesSpy::backbufferInfo(int32_t width, int32_t height, uint32_t color_fmt,
uint32_t depth_fmt, uint32_t stencil_fmt,
- bool resetViewportScissor) {
- GAPID_INFO("backbufferInfo(%" PRId32 ", %" PRId32 ", %u, %u, %u, %d)\n", width, height,
- color_fmt, depth_fmt, stencil_fmt, resetViewportScissor);
+ bool resetViewportScissor, bool preserveBuffersOnSwap) {
+ GAPID_INFO("backbufferInfo(%" PRId32 ", %" PRId32 ", %u, %u, %u, %d, %d)\n", width, height,
+ color_fmt, depth_fmt, stencil_fmt, resetViewportScissor, preserveBuffersOnSwap);
Observations observations;
do {
std::shared_ptr<Context> l_context = this->Contexts[this->CurrentThread];
std::shared_ptr<Context> l_GetContext_139_result = l_context;
std::shared_ptr<Context> l_ctx = l_GetContext_139_result;
+ l_ctx->mPreserveBuffersOnSwap = preserveBuffersOnSwap;
std::shared_ptr<Framebuffer> l_backbuffer =
l_ctx->mInstances.mFramebuffers[(FramebufferId)(0)];
RenderbufferId l_color_id =
@@ -6248,7 +6250,8 @@
observe(observations.mWrites);
gapic::coder::gles::BackbufferInfo coder(observations, width, height, color_fmt, depth_fmt,
- stencil_fmt, resetViewportScissor);
+ stencil_fmt, resetViewportScissor,
+ preserveBuffersOnSwap);
mEncoder->Object(&coder);
}
diff --git a/cc/gapii/gles_types.h b/cc/gapii/gles_types.h
index 27bbefe..4095149 100644
--- a/cc/gapii/gles_types.h
+++ b/cc/gapii/gles_types.h
@@ -1326,6 +1326,10 @@
mInstances = v;
return *this;
}
+ inline Context& SetPreserveBuffersOnSwap(bool v) {
+ mPreserveBuffersOnSwap = v;
+ return *this;
+ }
ContextID mIdentifier;
BlendState mBlending;
@@ -1343,6 +1347,7 @@
uint32_t mGenerateMipmapHint;
GLenumToS32 mPixelStorage;
Objects mInstances;
+ bool mPreserveBuffersOnSwap;
};
typedef std::unordered_map<CGLContextObj, std::shared_ptr<Context>> CGLContextObjToContext__R;
diff --git a/cc/gapii/spy.cpp b/cc/gapii/spy.cpp
index ff25f08..66e30d8 100644
--- a/cc/gapii/spy.cpp
+++ b/cc/gapii/spy.cpp
@@ -28,8 +28,10 @@
namespace {
-const uint32_t EGL_WIDTH = 0x3057;
-const uint32_t EGL_HEIGHT = 0x3056;
+const uint32_t EGL_WIDTH = 0x3057;
+const uint32_t EGL_HEIGHT = 0x3056;
+const uint32_t EGL_SWAP_BEHAVIOR = 0x3093;
+const uint32_t EGL_BUFFER_PRESERVED = 0x3094;
const uint32_t GLX_WIDTH = 0x801D;
const uint32_t GLX_HEIGHT = 0x801E;
@@ -86,11 +88,20 @@
if (res != 0 && draw != nullptr) {
int width = 0;
int height = 0;
+ int swapBehavior = 0;
mImports.eglQuerySurface(display, draw, EGL_WIDTH, &width);
mImports.eglQuerySurface(display, draw, EGL_HEIGHT, &height);
+ mImports.eglQuerySurface(display, draw, EGL_SWAP_BEHAVIOR, &swapBehavior);
+
+ bool resetViewportScissor = true;
+ bool preserveBuffersOnSwap = swapBehavior == EGL_BUFFER_PRESERVED;
// TODO: Probe formats
- GlesSpy::backbufferInfo(width, height, GL_RGBA8, GL_DEPTH_COMPONENT16, GL_STENCIL_INDEX8, true);
+ GlesSpy::backbufferInfo(
+ width, height,
+ GL_RGBA8, GL_DEPTH_COMPONENT16, GL_STENCIL_INDEX8,
+ resetViewportScissor,
+ preserveBuffersOnSwap);
}
return res;
@@ -104,8 +115,11 @@
#if TARGET_OS == GAPID_OS_WINDOWS
wgl::FramebufferInfo info;
wgl::getFramebufferInfo(hdc, info);
- GlesSpy::backbufferInfo(info.width, info.height,
- info.colorFormat, info.depthFormat, info.stencilFormat, true);
+ GlesSpy::backbufferInfo(
+ info.width, info.height,
+ info.colorFormat, info.depthFormat, info.stencilFormat,
+ /* resetViewportScissor */ true,
+ /* preserveBuffersOnSwap */ false);
#endif // TARGET_OS
}
@@ -129,7 +143,11 @@
int height = bounds[3] - bounds[1]; // size.y - origin.y
// TODO: Probe formats
- GlesSpy::backbufferInfo(width, height, GL_RGBA8, GL_DEPTH_COMPONENT16, GL_STENCIL_INDEX8, true);
+ GlesSpy::backbufferInfo(
+ width, height,
+ GL_RGBA8, GL_DEPTH_COMPONENT16, GL_STENCIL_INDEX8,
+ /* resetViewportScissor */ true,
+ /* preserveBuffersOnSwap */ false);
}
return err;
}
@@ -145,7 +163,11 @@
mImports.glXQueryDrawable(display, draw, GLX_HEIGHT, &height);
// TODO: Probe formats
- GlesSpy::backbufferInfo(width, height, GL_RGBA8, GL_DEPTH_COMPONENT16, GL_STENCIL_INDEX8, true);
+ GlesSpy::backbufferInfo(
+ width, height,
+ GL_RGBA8, GL_DEPTH_COMPONENT16, GL_STENCIL_INDEX8,
+ /* resetViewportScissor */ true,
+ /* preserveBuffersOnSwap */ false);
}
return res;
@@ -163,7 +185,10 @@
// TODO: Probe formats
GlesSpy::backbufferInfo(
- width, height, GL_RGBA8, GL_DEPTH_COMPONENT16, GL_STENCIL_INDEX8, true);
+ width, height,
+ GL_RGBA8, GL_DEPTH_COMPONENT16, GL_STENCIL_INDEX8,
+ /* resetViewportScissor */ true,
+ /* preserveBuffersOnSwap */ false);
}
return res;
diff --git a/cc/gapir/context.cpp b/cc/gapir/context.cpp
index 0da3937..613fe98 100644
--- a/cc/gapir/context.cpp
+++ b/cc/gapir/context.cpp
@@ -154,6 +154,7 @@
});
interpreter->registerFunction(gfxapi::Ids::BackbufferInfo, [this](Stack* stack, bool) {
+ stack->pop<bool>(); /* preserveBuffersOnSwap - ignored */
bool resetViewportScissor = stack->pop<bool>();
uint32_t stencil_fmt = stack->pop<uint32_t>();
uint32_t depth_fmt = stack->pop<uint32_t>();
@@ -180,10 +181,22 @@
case static_cast<uint32_t>(gfxapi::GLenum::GL_DEPTH24_STENCIL8):
stencilSize = 8;
}
- GAPID_INFO("backbufferInfo(%d, %d, 0x%x, 0x%x, 0x%x)\n",
- width, height, color_fmt, depth_fmt, stencil_fmt);
- if (mBoundRenderer == nullptr) {
- GAPID_INFO("backbufferInfo called without a bound renderer\n");
+ if (stack->isValid()) {
+ GAPID_INFO("backbufferInfo(%d, %d, 0x%x, 0x%x, 0x%x)\n",
+ width, height, color_fmt, depth_fmt, stencil_fmt,
+ resetViewportScissor ? "true" : "false");
+ if (mBoundRenderer == nullptr) {
+ GAPID_INFO("backbufferInfo called without a bound renderer\n");
+ return false;
+ }
+ mBoundRenderer->setBackbuffer(width, height, depthSize, stencilSize);
+ if (resetViewportScissor) {
+ gfxapi::glViewport(0, 0, width, height);
+ gfxapi::glScissor(0, 0, width, height);
+ }
+ return true;
+ } else {
+ GAPID_WARNING("Error during calling function replayCreateRenderer\n");
return false;
}
mBoundRenderer->setBackbuffer(width, height, depthSize, stencilSize);
diff --git a/cc/gapir/renderer.h b/cc/gapir/renderer.h
index f0c4d87..ce17fd9 100644
--- a/cc/gapir/renderer.h
+++ b/cc/gapir/renderer.h
@@ -37,7 +37,7 @@
// Makes the current renderer active.
virtual void bind() = 0;
- //Makes the current renderer inactive.
+ // Makes the current renderer inactive.
virtual void unbind() = 0;
// Returns the name of the renderer's created graphics context.
diff --git a/cc/gapir/windows/renderer.cpp b/cc/gapir/windows/renderer.cpp
index e7900bf..c7c23e8 100644
--- a/cc/gapir/windows/renderer.cpp
+++ b/cc/gapir/windows/renderer.cpp
@@ -156,7 +156,7 @@
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
- pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
+ pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
pfd.cDepthBits = depthSize;
@@ -235,4 +235,3 @@
}
} // namespace gapir
-
diff --git a/gfxapi/gles/api.go b/gfxapi/gles/api.go
index be27456..f6856d4 100644
--- a/gfxapi/gles/api.go
+++ b/gfxapi/gles/api.go
@@ -16319,17 +16319,18 @@
////////////////////////////////////////////////////////////////////////////////
type BackbufferInfo struct {
binary.Generate
- observations atom.Observations
- Width int32
- Height int32
- ColorFmt GLenum
- DepthFmt GLenum
- StencilFmt GLenum
- ResetViewportScissor bool
+ observations atom.Observations
+ Width int32
+ Height int32
+ ColorFmt GLenum
+ DepthFmt GLenum
+ StencilFmt GLenum
+ ResetViewportScissor bool
+ PreserveBuffersOnSwap bool
}
func (a *BackbufferInfo) String() string {
- return fmt.Sprintf("backbufferInfo(width: %v, height: %v, color_fmt: %v, depth_fmt: %v, stencil_fmt: %v, resetViewportScissor: %v)", a.Width, a.Height, a.ColorFmt, a.DepthFmt, a.StencilFmt, a.ResetViewportScissor)
+ return fmt.Sprintf("backbufferInfo(width: %v, height: %v, color_fmt: %v, depth_fmt: %v, stencil_fmt: %v, resetViewportScissor: %v, preserveBuffersOnSwap: %v)", a.Width, a.Height, a.ColorFmt, a.DepthFmt, a.StencilFmt, a.ResetViewportScissor, a.PreserveBuffersOnSwap)
}
// AddRead appends a new read observation to the atom of the range rng with
@@ -16872,6 +16873,7 @@
GenerateMipmapHint GLenum
PixelStorage GLenumːs32ᵐ
Instances Objects
+ PreserveBuffersOnSwap bool
}
func (c *Context) Init() {
@@ -18065,8 +18067,8 @@
func NewSwitchThread(ThreadID ThreadID) *SwitchThread {
return &SwitchThread{ThreadID: ThreadID}
}
-func NewBackbufferInfo(Width int32, Height int32, Color_fmt GLenum, Depth_fmt GLenum, Stencil_fmt GLenum, ResetViewportScissor bool) *BackbufferInfo {
- return &BackbufferInfo{Width: Width, Height: Height, ColorFmt: Color_fmt, DepthFmt: Depth_fmt, StencilFmt: Stencil_fmt, ResetViewportScissor: ResetViewportScissor}
+func NewBackbufferInfo(Width int32, Height int32, Color_fmt GLenum, Depth_fmt GLenum, Stencil_fmt GLenum, ResetViewportScissor bool, PreserveBuffersOnSwap bool) *BackbufferInfo {
+ return &BackbufferInfo{Width: Width, Height: Height, ColorFmt: Color_fmt, DepthFmt: Depth_fmt, StencilFmt: Stencil_fmt, ResetViewportScissor: ResetViewportScissor, PreserveBuffersOnSwap: PreserveBuffersOnSwap}
}
func NewStartTimer(Index uint8) *StartTimer {
return &StartTimer{Index: Index}
diff --git a/gfxapi/gles/custom_replay.go b/gfxapi/gles/custom_replay.go
index 69aa694..43d7977 100644
--- a/gfxapi/gles/custom_replay.go
+++ b/gfxapi/gles/custom_replay.go
@@ -120,7 +120,7 @@
}
func (i TexturePointer) value(b *builder.Builder, a atom.Atom, s *gfxapi.State) value.Value {
- if i.Pointer.Address == 0 {
+ if i.Pointer.Address == 0 || getContext(s).BoundBuffers[GLenum_GL_PIXEL_UNPACK_BUFFER] != 0 {
return value.AbsolutePointer(i.Pointer.Address)
} else {
return value.RemappedPointer(i.Pointer.Address)
diff --git a/gfxapi/gles/gles.api b/gfxapi/gles/gles.api
index 8469c8e..b5def80 100644
--- a/gfxapi/gles/gles.api
+++ b/gfxapi/gles/gles.api
@@ -390,6 +390,7 @@
GLenum GenerateMipmapHint = GL_DONT_CARE
map!(GLenum, s32) PixelStorage
Objects Instances
+ bool PreserveBuffersOnSwap
}
type u64 ThreadID
diff --git a/gfxapi/gles/gles_binary.go b/gfxapi/gles/gles_binary.go
index ea0243f..9870355 100644
--- a/gfxapi/gles/gles_binary.go
+++ b/gfxapi/gles/gles_binary.go
@@ -388,7 +388,7 @@
var (
binaryIDArchitecture = binary.ID{0x14, 0x53, 0xe8, 0x31, 0x7d, 0x20, 0x5f, 0xbd, 0xad, 0x68, 0x48, 0x67, 0xeb, 0xf6, 0x1c, 0x4f, 0xe8, 0xfc, 0x0e, 0x01}
- binaryIDBackbufferInfo = binary.ID{0x18, 0x3c, 0x07, 0xe1, 0x0c, 0x71, 0x64, 0xee, 0xaa, 0x70, 0x7a, 0xb3, 0xca, 0xbe, 0x36, 0x00, 0xe8, 0xeb, 0x8c, 0xed}
+ binaryIDBackbufferInfo = binary.ID{0x3b, 0x71, 0x56, 0x1e, 0xbc, 0xdf, 0xd7, 0x44, 0xcf, 0x32, 0xc5, 0x65, 0xe5, 0x66, 0xf0, 0x8f, 0x1b, 0x28, 0x23, 0xa7}
binaryIDColor = binary.ID{0xe7, 0x31, 0x0f, 0x05, 0x26, 0x27, 0x37, 0x3a, 0xc4, 0xbb, 0x59, 0xea, 0xc0, 0x41, 0xb0, 0xa7, 0x8f, 0x15, 0x58, 0xb4}
binaryIDBlendState = binary.ID{0x54, 0x6b, 0x98, 0xbd, 0x32, 0x48, 0x57, 0xe0, 0x34, 0x7a, 0xfa, 0x8d, 0x92, 0x95, 0x4b, 0x07, 0xdd, 0x96, 0x3a, 0x2a}
binaryIDSliceInfo = binary.ID{0x8e, 0xab, 0xab, 0x1b, 0x89, 0x6a, 0x43, 0x9a, 0x3c, 0xa7, 0xb8, 0x43, 0x28, 0x26, 0x72, 0x30, 0x78, 0x26, 0x38, 0xf9}
@@ -441,7 +441,7 @@
binaryIDVertexArray = binary.ID{0x8c, 0x9a, 0x34, 0xfe, 0x61, 0x2a, 0x2d, 0x57, 0x19, 0x43, 0x24, 0x95, 0xf6, 0x1e, 0x79, 0x97, 0x85, 0x3f, 0xee, 0xc4}
binaryIDQuery = binary.ID{0x9e, 0x4e, 0xd0, 0x26, 0x26, 0xf8, 0x9d, 0x8e, 0xb5, 0x02, 0x2f, 0xde, 0x80, 0xb3, 0xe9, 0x09, 0xf5, 0x4c, 0x1e, 0xf2}
binaryIDObjects = binary.ID{0x8a, 0x05, 0xaa, 0xf5, 0xa8, 0x57, 0xb0, 0xf1, 0x13, 0x48, 0x39, 0x76, 0xec, 0x1e, 0x47, 0x0b, 0x6c, 0x3b, 0xf6, 0xe0}
- binaryIDContext = binary.ID{0x5d, 0x15, 0x38, 0x06, 0x50, 0x11, 0xdd, 0x3b, 0xf6, 0x52, 0x52, 0xca, 0xc5, 0x29, 0x63, 0xdc, 0xe5, 0x1d, 0x52, 0x4a}
+ binaryIDContext = binary.ID{0x2d, 0x31, 0xd7, 0x8d, 0xe9, 0x76, 0xe7, 0x8c, 0xd4, 0xda, 0x77, 0xca, 0x1b, 0x5f, 0x8a, 0xc3, 0xa9, 0x35, 0xb2, 0x2c}
binaryIDEGLConfig = binary.ID{0xc1, 0xea, 0x31, 0x3f, 0xd1, 0xf0, 0x52, 0x99, 0x82, 0x15, 0x2a, 0x15, 0xc0, 0x95, 0x93, 0x16, 0x2d, 0xd0, 0xaa, 0x58}
binaryIDEGLContext = binary.ID{0x7e, 0xd7, 0x09, 0xd5, 0xdb, 0xde, 0xd4, 0xf4, 0xc2, 0x44, 0xa3, 0x47, 0xb0, 0x05, 0x91, 0x42, 0x91, 0x5f, 0x12, 0x55}
binaryIDEGLDisplay = binary.ID{0xdd, 0x44, 0x8d, 0x9b, 0x11, 0x43, 0x6e, 0xec, 0x7b, 0xc7, 0x17, 0x93, 0x81, 0x62, 0x0b, 0xaa, 0x5f, 0xe0, 0xdd, 0x10}
@@ -876,6 +876,9 @@
if err := e.Bool(o.ResetViewportScissor); err != nil {
return err
}
+ if err := e.Bool(o.PreserveBuffersOnSwap); err != nil {
+ return err
+ }
return nil
}
func doDecodeBackbufferInfo(d binary.Decoder, o *BackbufferInfo) error {
@@ -912,6 +915,11 @@
} else {
o.ResetViewportScissor = bool(obj)
}
+ if obj, err := d.Bool(); err != nil {
+ return err
+ } else {
+ o.PreserveBuffersOnSwap = bool(obj)
+ }
return nil
}
func doSkipBackbufferInfo(d binary.Decoder) error {
@@ -936,6 +944,9 @@
if _, err := d.Bool(); err != nil {
return err
}
+ if _, err := d.Bool(); err != nil {
+ return err
+ }
return nil
}
func (*binaryClassBackbufferInfo) ID() binary.ID { return binaryIDBackbufferInfo }
@@ -965,6 +976,7 @@
{Declared: "DepthFmt", Type: &schema.Primitive{Name: "GLenum", Method: schema.Uint32}},
{Declared: "StencilFmt", Type: &schema.Primitive{Name: "GLenum", Method: schema.Uint32}},
{Declared: "ResetViewportScissor", Type: &schema.Primitive{Name: "bool", Method: schema.Bool}},
+ {Declared: "PreserveBuffersOnSwap", Type: &schema.Primitive{Name: "bool", Method: schema.Bool}},
},
}
@@ -5620,6 +5632,9 @@
if err := e.Value(&o.Instances); err != nil {
return err
}
+ if err := e.Bool(o.PreserveBuffersOnSwap); err != nil {
+ return err
+ }
return nil
}
func doDecodeContext(d binary.Decoder, o *Context) error {
@@ -5830,6 +5845,11 @@
if err := d.Value(&o.Instances); err != nil {
return err
}
+ if obj, err := d.Bool(); err != nil {
+ return err
+ } else {
+ o.PreserveBuffersOnSwap = bool(obj)
+ }
return nil
}
func doSkipContext(d binary.Decoder) error {
@@ -5956,6 +5976,9 @@
if err := d.SkipValue((*Objects)(nil)); err != nil {
return err
}
+ if _, err := d.Bool(); err != nil {
+ return err
+ }
return nil
}
func (*binaryClassContext) ID() binary.ID { return binaryIDContext }
@@ -5995,6 +6018,7 @@
{Declared: "GenerateMipmapHint", Type: &schema.Primitive{Name: "GLenum", Method: schema.Uint32}},
{Declared: "PixelStorage", Type: &schema.Map{Alias: "GLenumːs32ᵐ", KeyType: &schema.Primitive{Name: "GLenum", Method: schema.Uint32}, ValueType: &schema.Primitive{Name: "int32", Method: schema.Int32}}},
{Declared: "Instances", Type: &schema.Struct{Name: "Objects", ID: (*Objects)(nil).Class().ID()}},
+ {Declared: "PreserveBuffersOnSwap", Type: &schema.Primitive{Name: "bool", Method: schema.Bool}},
},
}
diff --git a/gfxapi/gles/replay.go b/gfxapi/gles/replay.go
index b93d934..fe2526e 100644
--- a/gfxapi/gles/replay.go
+++ b/gfxapi/gles/replay.go
@@ -17,6 +17,7 @@
import (
"android.googlesource.com/platform/tools/gpu/atom"
"android.googlesource.com/platform/tools/gpu/atom/transform"
+ "android.googlesource.com/platform/tools/gpu/config"
"android.googlesource.com/platform/tools/gpu/database"
"android.googlesource.com/platform/tools/gpu/gfxapi"
"android.googlesource.com/platform/tools/gpu/log"
@@ -65,13 +66,15 @@
flags service.TimingFlags
}
-func (a api) ReplayTransforms(
+func (a api) Replay(
ctx replay.Context,
- config replay.Config,
+ cfg replay.Config,
requests []replay.Request,
device *service.Device,
- db database.Database,
- logger log.Logger) atom.Transforms {
+ atoms atom.List,
+ out atom.Writer,
+ d database.Database,
+ l log.Logger) error {
transforms := atom.Transforms{}
@@ -100,37 +103,62 @@
case timeCallsRequest:
profiling = true
- transforms.Add(timingInfo(req.flags, req.out, device, db, logger))
+ transforms.Add(timingInfo(req.flags, req.out, device, d, l))
}
}
if !profiling {
// Not profiling. Add optimisation transforms.
- transforms.Add(earlyTerminator, skipDrawCalls)
+ transforms.Add(earlyTerminator)
+
+ // Check to see if any contexts use the 'preserveBuffersOnSwap' flag.
+ // If it is used, we can't skip draw calls or display the
+ // undefined-framebuffer pattern.
+ preserveBuffersOnSwap := false
+ for _, a := range atoms.Atoms {
+ if b, ok := a.(*BackbufferInfo); ok && b.PreserveBuffersOnSwap {
+ preserveBuffersOnSwap = true
+ break
+ }
+ }
+
+ if !preserveBuffersOnSwap {
+ transforms.Add(skipDrawCalls, undefinedFramebuffer(d, l))
+ }
}
transforms.Add(
injector,
- remapAttributes())
+ remapAttributes(),
+ )
// Device-dependent transforms.
transforms.Add(
- decompressTextures(device, &path.Capture{ID: ctx.Capture}, db, logger),
- precisionStrip(device, db, logger),
+ decompressTextures(device, &path.Capture{ID: ctx.Capture}, d, l),
+ precisionStrip(device, d, l),
halfFloatOESToHalfFloatARB(device))
- if c, ok := config.(drawConfig); ok && c.wireframe {
- transforms.Add(wireframe(db, logger))
+ if c, ok := cfg.(drawConfig); ok && c.wireframe {
+ transforms.Add(wireframe(d, l))
}
// Cleanup
transforms.Add(&destroyResourcesAtEOS{
state: gfxapi.NewState(),
- db: db,
- logger: logger,
+ db: d,
+ logger: l,
})
- return transforms
+ if config.DebugReplay {
+ log.Infof(l, "Replaying %d atoms using transform chain:", len(atoms.Atoms))
+ for i, t := range transforms {
+ log.Infof(l, "(%d) %#v", i, t)
+ }
+ }
+
+ transforms.Transform(atoms, out)
+
+ return nil
}
func (a api) QueryColorBuffer(ctx *replay.Context, mgr *replay.Manager, after atom.ID, width, height uint32, wireframe bool) <-chan replay.Image {
diff --git a/gfxapi/gles/replay_writer.go b/gfxapi/gles/replay_writer.go
index b15db51..adc6ac5 100644
--- a/gfxapi/gles/replay_writer.go
+++ b/gfxapi/gles/replay_writer.go
@@ -250,7 +250,7 @@
var funcInfoReplayCreateRenderer = builder.FunctionInfo{ID: 216, ReturnType: protocol.TypeVoid, Parameters: 1}
var funcInfoReplayBindRenderer = builder.FunctionInfo{ID: 217, ReturnType: protocol.TypeVoid, Parameters: 1}
var funcInfoSwitchThread = builder.FunctionInfo{ID: 218, ReturnType: protocol.TypeVoid, Parameters: 1}
-var funcInfoBackbufferInfo = builder.FunctionInfo{ID: 219, ReturnType: protocol.TypeVoid, Parameters: 6}
+var funcInfoBackbufferInfo = builder.FunctionInfo{ID: 219, ReturnType: protocol.TypeVoid, Parameters: 7}
var funcInfoStartTimer = builder.FunctionInfo{ID: 220, ReturnType: protocol.TypeVoid, Parameters: 1}
var funcInfoStopTimer = builder.FunctionInfo{ID: 221, ReturnType: protocol.TypeUint64, Parameters: 1}
var funcInfoFlushPostBuffer = builder.FunctionInfo{ID: 222, ReturnType: protocol.TypeVoid, Parameters: 0}
@@ -705,7 +705,7 @@
ctx := GetContext_15_result // Contextʳ
a := ϟa.Arrays.Slice(uint64(int32(0)), uint64(ϟa.Count), ϟs) // VertexArrayIdˢ
for i := int32(int32(0)); i < ϟa.Count; i++ {
- ctx.Instances.VertexArrays[a.Index(uint64(i), ϟs).replayRead(ϟa, ϟs, ϟd, ϟl, ϟb)] = (*VertexArray)(nil)
+ delete(ctx.Instances.VertexArrays, a.Index(uint64(i), ϟs).replayRead(ϟa, ϟs, ϟd, ϟl, ϟb))
}
ϟb.Push(value.S32(ϟa.Count))
ϟb.Push(ϟa.Arrays.value())
@@ -2300,7 +2300,7 @@
GetContext_62_result := context // Contextʳ
ctx := GetContext_62_result // Contextʳ
for i := int32(int32(0)); i < ϟa.Count; i++ {
- ctx.Instances.Textures[t.Index(uint64(i), ϟs).replayRead(ϟa, ϟs, ϟd, ϟl, ϟb)] = (*Texture)(nil)
+ delete(ctx.Instances.Textures, t.Index(uint64(i), ϟs).replayRead(ϟa, ϟs, ϟd, ϟl, ϟb))
}
ϟb.Push(value.S32(ϟa.Count))
ϟb.Push(ϟa.Textures.value())
@@ -2733,7 +2733,7 @@
GetContext_70_result := context // Contextʳ
ctx := GetContext_70_result // Contextʳ
for i := int32(int32(0)); i < ϟa.Count; i++ {
- ctx.Instances.Framebuffers[f.Index(uint64(i), ϟs).replayRead(ϟa, ϟs, ϟd, ϟl, ϟb)] = (*Framebuffer)(nil)
+ delete(ctx.Instances.Framebuffers, f.Index(uint64(i), ϟs).replayRead(ϟa, ϟs, ϟd, ϟl, ϟb))
}
ϟb.Push(value.S32(ϟa.Count))
ϟb.Push(ϟa.Framebuffers.value())
@@ -2850,7 +2850,7 @@
GetContext_75_result := context // Contextʳ
ctx := GetContext_75_result // Contextʳ
for i := int32(int32(0)); i < ϟa.Count; i++ {
- ctx.Instances.Renderbuffers[r.Index(uint64(i), ϟs).replayRead(ϟa, ϟs, ϟd, ϟl, ϟb)] = (*Renderbuffer)(nil)
+ delete(ctx.Instances.Renderbuffers, r.Index(uint64(i), ϟs).replayRead(ϟa, ϟs, ϟd, ϟl, ϟb))
}
ϟb.Push(value.S32(ϟa.Count))
ϟb.Push(ϟa.Renderbuffers.value())
@@ -3026,7 +3026,7 @@
GetContext_81_result := context // Contextʳ
ctx := GetContext_81_result // Contextʳ
for i := int32(int32(0)); i < ϟa.Count; i++ {
- ctx.Instances.Buffers[b.Index(uint64(i), ϟs).replayRead(ϟa, ϟs, ϟd, ϟl, ϟb)] = (*Buffer)(nil)
+ delete(ctx.Instances.Buffers, b.Index(uint64(i), ϟs).replayRead(ϟa, ϟs, ϟd, ϟl, ϟb))
}
ϟb.Push(value.S32(ϟa.Count))
ϟb.Push(ϟa.Buffers.value())
@@ -3128,7 +3128,7 @@
ctx := GetContext_85_result // Contextʳ
s := ctx.Instances.Shaders.Get(ϟa.Shader) // Shaderʳ
s.Deletable = true
- ctx.Instances.Shaders[ϟa.Shader] = (*Shader)(nil)
+ delete(ctx.Instances.Shaders, ϟa.Shader)
if key, remap := ϟa.Shader.remap(ϟa, ϟs); remap {
loadRemap(ϟb, key, protocol.TypeUint32, ϟa.Shader.value(ϟb, ϟa, ϟs))
} else {
@@ -3363,7 +3363,7 @@
context := ϟc.Contexts.Get(ϟc.CurrentThread) // Contextʳ
GetContext_93_result := context // Contextʳ
ctx := GetContext_93_result // Contextʳ
- ctx.Instances.Programs[ϟa.Program] = (*Program)(nil)
+ delete(ctx.Instances.Programs, ϟa.Program)
if key, remap := ϟa.Program.remap(ϟa, ϟs); remap {
loadRemap(ϟb, key, protocol.TypeUint32, ϟa.Program.value(ϟb, ϟa, ϟs))
} else {
@@ -3412,7 +3412,7 @@
ctx := GetContext_95_result // Contextʳ
p := ctx.Instances.Programs.Get(ϟa.Program) // Programʳ
s := ctx.Instances.Shaders.Get(ϟa.Shader) // Shaderʳ
- p.Shaders[s.Type] = ShaderId(uint32(0))
+ delete(p.Shaders, s.Type)
if key, remap := ϟa.Program.remap(ϟa, ϟs); remap {
loadRemap(ϟb, key, protocol.TypeUint32, ϟa.Program.value(ϟb, ϟa, ϟs))
} else {
@@ -4708,7 +4708,7 @@
GetContext_131_result := context // Contextʳ
ctx := GetContext_131_result // Contextʳ
for i := int32(int32(0)); i < ϟa.Count; i++ {
- ctx.Instances.Queries[q.Index(uint64(i), ϟs).replayRead(ϟa, ϟs, ϟd, ϟl, ϟb)] = (*Query)(nil)
+ delete(ctx.Instances.Queries, q.Index(uint64(i), ϟs).replayRead(ϟa, ϟs, ϟd, ϟl, ϟb))
}
ϟb.Push(value.S32(ϟa.Count))
ϟb.Push(ϟa.Queries.value())
@@ -4930,7 +4930,7 @@
ctx := GetContext_135_result // Contextʳ
a := ϟa.Arrays.Slice(uint64(uint32(0)), uint64(ϟa.Count), ϟs) // VertexArrayIdˢ
for i := uint32(uint32(0)); i < ϟa.Count; i++ {
- ctx.Instances.VertexArrays[a.Index(uint64(i), ϟs).replayRead(ϟa, ϟs, ϟd, ϟl, ϟb)] = (*VertexArray)(nil)
+ delete(ctx.Instances.VertexArrays, a.Index(uint64(i), ϟs).replayRead(ϟa, ϟs, ϟd, ϟl, ϟb))
}
ϟb.Push(value.U32(ϟa.Count))
ϟb.Push(ϟa.Arrays.value())
@@ -5040,7 +5040,7 @@
GetContext_137_result := context // Contextʳ
ctx := GetContext_137_result // Contextʳ
for i := int32(int32(0)); i < ϟa.Count; i++ {
- ctx.Instances.Queries[q.Index(uint64(i), ϟs).replayRead(ϟa, ϟs, ϟd, ϟl, ϟb)] = (*Query)(nil)
+ delete(ctx.Instances.Queries, q.Index(uint64(i), ϟs).replayRead(ϟa, ϟs, ϟd, ϟl, ϟb))
}
ϟb.Push(value.S32(ϟa.Count))
ϟb.Push(ϟa.Queries.value())
@@ -5198,9 +5198,10 @@
ϟc := getState(ϟs)
_ = ϟc
ϟa.observations.ApplyReads(ϟs.Memory[memory.ApplicationPool])
- context := ϟc.Contexts.Get(ϟc.CurrentThread) // Contextʳ
- GetContext_139_result := context // Contextʳ
- ctx := GetContext_139_result // Contextʳ
+ context := ϟc.Contexts.Get(ϟc.CurrentThread) // Contextʳ
+ GetContext_139_result := context // Contextʳ
+ ctx := GetContext_139_result // Contextʳ
+ ctx.PreserveBuffersOnSwap = ϟa.PreserveBuffersOnSwap
backbuffer := ctx.Instances.Framebuffers.Get(FramebufferId(uint32(0))) // Framebufferʳ
color_id := RenderbufferId(backbuffer.Attachments.Get(GLenum_GL_COLOR_ATTACHMENT0).Object) // RenderbufferId
color_buffer := ctx.Instances.Renderbuffers.Get(color_id) // Renderbufferʳ
@@ -5229,6 +5230,7 @@
ϟb.Push(value.U32(ϟa.DepthFmt))
ϟb.Push(value.U32(ϟa.StencilFmt))
ϟb.Push(value.Bool(ϟa.ResetViewportScissor))
+ ϟb.Push(value.Bool(ϟa.PreserveBuffersOnSwap))
ϟb.Call(funcInfoBackbufferInfo)
ϟa.observations.ApplyWrites(ϟs.Memory[memory.ApplicationPool])
_, _, _, _, _, _, _, _, _, _ = context, GetContext_139_result, ctx, backbuffer, color_id, color_buffer, depth_id, depth_buffer, stencil_id, stencil_buffer
diff --git a/gfxapi/gles/state_mutator.go b/gfxapi/gles/state_mutator.go
index 1b45587..8036812 100644
--- a/gfxapi/gles/state_mutator.go
+++ b/gfxapi/gles/state_mutator.go
@@ -930,7 +930,7 @@
ctx := GetContext_15_result // Contextʳ
a := ϟa.Arrays.Slice(uint64(int32(0)), uint64(ϟa.Count), ϟs) // VertexArrayIdˢ
for i := int32(int32(0)); i < ϟa.Count; i++ {
- ctx.Instances.VertexArrays[a.Index(uint64(i), ϟs).Read(ϟs, ϟd, ϟl)] = (*VertexArray)(nil)
+ delete(ctx.Instances.VertexArrays, a.Index(uint64(i), ϟs).Read(ϟs, ϟd, ϟl))
}
ϟa.observations.ApplyWrites(ϟs.Memory[memory.ApplicationPool])
_, _, _, _ = context, GetContext_15_result, ctx, a
@@ -1994,7 +1994,7 @@
GetContext_62_result := context // Contextʳ
ctx := GetContext_62_result // Contextʳ
for i := int32(int32(0)); i < ϟa.Count; i++ {
- ctx.Instances.Textures[t.Index(uint64(i), ϟs).Read(ϟs, ϟd, ϟl)] = (*Texture)(nil)
+ delete(ctx.Instances.Textures, t.Index(uint64(i), ϟs).Read(ϟs, ϟd, ϟl))
}
ϟa.observations.ApplyWrites(ϟs.Memory[memory.ApplicationPool])
_, _, _, _ = t, context, GetContext_62_result, ctx
@@ -2306,7 +2306,7 @@
GetContext_70_result := context // Contextʳ
ctx := GetContext_70_result // Contextʳ
for i := int32(int32(0)); i < ϟa.Count; i++ {
- ctx.Instances.Framebuffers[f.Index(uint64(i), ϟs).Read(ϟs, ϟd, ϟl)] = (*Framebuffer)(nil)
+ delete(ctx.Instances.Framebuffers, f.Index(uint64(i), ϟs).Read(ϟs, ϟd, ϟl))
}
ϟa.observations.ApplyWrites(ϟs.Memory[memory.ApplicationPool])
_, _, _, _ = f, context, GetContext_70_result, ctx
@@ -2390,7 +2390,7 @@
GetContext_75_result := context // Contextʳ
ctx := GetContext_75_result // Contextʳ
for i := int32(int32(0)); i < ϟa.Count; i++ {
- ctx.Instances.Renderbuffers[r.Index(uint64(i), ϟs).Read(ϟs, ϟd, ϟl)] = (*Renderbuffer)(nil)
+ delete(ctx.Instances.Renderbuffers, r.Index(uint64(i), ϟs).Read(ϟs, ϟd, ϟl))
}
ϟa.observations.ApplyWrites(ϟs.Memory[memory.ApplicationPool])
_, _, _, _ = r, context, GetContext_75_result, ctx
@@ -2520,7 +2520,7 @@
GetContext_81_result := context // Contextʳ
ctx := GetContext_81_result // Contextʳ
for i := int32(int32(0)); i < ϟa.Count; i++ {
- ctx.Instances.Buffers[b.Index(uint64(i), ϟs).Read(ϟs, ϟd, ϟl)] = (*Buffer)(nil)
+ delete(ctx.Instances.Buffers, b.Index(uint64(i), ϟs).Read(ϟs, ϟd, ϟl))
}
ϟa.observations.ApplyWrites(ϟs.Memory[memory.ApplicationPool])
_, _, _, _ = b, context, GetContext_81_result, ctx
@@ -2592,7 +2592,7 @@
ctx := GetContext_85_result // Contextʳ
s := ctx.Instances.Shaders.Get(ϟa.Shader) // Shaderʳ
s.Deletable = true
- ctx.Instances.Shaders[ϟa.Shader] = (*Shader)(nil)
+ delete(ctx.Instances.Shaders, ϟa.Shader)
ϟa.observations.ApplyWrites(ϟs.Memory[memory.ApplicationPool])
_, _, _, _ = context, GetContext_85_result, ctx, s
return nil
@@ -2745,7 +2745,7 @@
context := ϟc.Contexts.Get(ϟc.CurrentThread) // Contextʳ
GetContext_93_result := context // Contextʳ
ctx := GetContext_93_result // Contextʳ
- ctx.Instances.Programs[ϟa.Program] = (*Program)(nil)
+ delete(ctx.Instances.Programs, ϟa.Program)
ϟa.observations.ApplyWrites(ϟs.Memory[memory.ApplicationPool])
_, _, _ = context, GetContext_93_result, ctx
return nil
@@ -2773,7 +2773,7 @@
ctx := GetContext_95_result // Contextʳ
p := ctx.Instances.Programs.Get(ϟa.Program) // Programʳ
s := ctx.Instances.Shaders.Get(ϟa.Shader) // Shaderʳ
- p.Shaders[s.Type] = ShaderId(uint32(0))
+ delete(p.Shaders, s.Type)
ϟa.observations.ApplyWrites(ϟs.Memory[memory.ApplicationPool])
_, _, _, _, _ = context, GetContext_95_result, ctx, p, s
return nil
@@ -3784,7 +3784,7 @@
GetContext_131_result := context // Contextʳ
ctx := GetContext_131_result // Contextʳ
for i := int32(int32(0)); i < ϟa.Count; i++ {
- ctx.Instances.Queries[q.Index(uint64(i), ϟs).Read(ϟs, ϟd, ϟl)] = (*Query)(nil)
+ delete(ctx.Instances.Queries, q.Index(uint64(i), ϟs).Read(ϟs, ϟd, ϟl))
}
ϟa.observations.ApplyWrites(ϟs.Memory[memory.ApplicationPool])
_, _, _, _ = q, context, GetContext_131_result, ctx
@@ -3910,7 +3910,7 @@
ctx := GetContext_135_result // Contextʳ
a := ϟa.Arrays.Slice(uint64(uint32(0)), uint64(ϟa.Count), ϟs) // VertexArrayIdˢ
for i := uint32(uint32(0)); i < ϟa.Count; i++ {
- ctx.Instances.VertexArrays[a.Index(uint64(i), ϟs).Read(ϟs, ϟd, ϟl)] = (*VertexArray)(nil)
+ delete(ctx.Instances.VertexArrays, a.Index(uint64(i), ϟs).Read(ϟs, ϟd, ϟl))
}
ϟa.observations.ApplyWrites(ϟs.Memory[memory.ApplicationPool])
_, _, _, _ = context, GetContext_135_result, ctx, a
@@ -3977,7 +3977,7 @@
GetContext_137_result := context // Contextʳ
ctx := GetContext_137_result // Contextʳ
for i := int32(int32(0)); i < ϟa.Count; i++ {
- ctx.Instances.Queries[q.Index(uint64(i), ϟs).Read(ϟs, ϟd, ϟl)] = (*Query)(nil)
+ delete(ctx.Instances.Queries, q.Index(uint64(i), ϟs).Read(ϟs, ϟd, ϟl))
}
ϟa.observations.ApplyWrites(ϟs.Memory[memory.ApplicationPool])
_, _, _, _ = q, context, GetContext_137_result, ctx
@@ -4068,9 +4068,10 @@
ϟc := getState(ϟs)
_ = ϟc
ϟa.observations.ApplyReads(ϟs.Memory[memory.ApplicationPool])
- context := ϟc.Contexts.Get(ϟc.CurrentThread) // Contextʳ
- GetContext_139_result := context // Contextʳ
- ctx := GetContext_139_result // Contextʳ
+ context := ϟc.Contexts.Get(ϟc.CurrentThread) // Contextʳ
+ GetContext_139_result := context // Contextʳ
+ ctx := GetContext_139_result // Contextʳ
+ ctx.PreserveBuffersOnSwap = ϟa.PreserveBuffersOnSwap
backbuffer := ctx.Instances.Framebuffers.Get(FramebufferId(uint32(0))) // Framebufferʳ
color_id := RenderbufferId(backbuffer.Attachments.Get(GLenum_GL_COLOR_ATTACHMENT0).Object) // RenderbufferId
color_buffer := ctx.Instances.Renderbuffers.Get(color_id) // Renderbufferʳ
diff --git a/gfxapi/gles/synthetic.api b/gfxapi/gles/synthetic.api
index f989d12..20affda 100644
--- a/gfxapi/gles/synthetic.api
+++ b/gfxapi/gles/synthetic.api
@@ -40,8 +40,10 @@
GLenum color_fmt,
GLenum depth_fmt,
GLenum stencil_fmt,
- bool resetViewportScissor) {
+ bool resetViewportScissor,
+ bool preserveBuffersOnSwap) {
ctx := GetContext()
+ ctx.PreserveBuffersOnSwap = preserveBuffersOnSwap
backbuffer := ctx.Instances.Framebuffers[0]
color_id := as!RenderbufferId(backbuffer.Attachments[GL_COLOR_ATTACHMENT0].Object)
diff --git a/gfxapi/gles/unknown_framebuffer.go b/gfxapi/gles/unknown_framebuffer.go
new file mode 100644
index 0000000..4d44c16
--- /dev/null
+++ b/gfxapi/gles/unknown_framebuffer.go
@@ -0,0 +1,137 @@
+// Copyright (C) 2015 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.
+
+package gles
+
+import (
+ "android.googlesource.com/platform/tools/gpu/atom"
+ "android.googlesource.com/platform/tools/gpu/database"
+ "android.googlesource.com/platform/tools/gpu/gfxapi"
+ "android.googlesource.com/platform/tools/gpu/log"
+ "android.googlesource.com/platform/tools/gpu/memory"
+)
+
+// undefinedFramebuffer adds a transform that will render a pattern into the
+// color buffer at the end of each frame.
+func undefinedFramebuffer(d database.Database, l log.Logger) atom.Transformer {
+ s := gfxapi.NewState()
+ return atom.Transform("DirtyFramebuffer", func(i atom.ID, a atom.Atom, out atom.Writer) {
+ a.Mutate(s, d, l)
+ out.Write(i, a)
+ if a.Flags().IsEndOfFrame() {
+ drawUndefinedFramebuffer(a, s, d, l, out)
+ }
+ })
+}
+
+func drawUndefinedFramebuffer(a atom.Atom, s *gfxapi.State, d database.Database, l log.Logger, out atom.Writer) error {
+ const (
+ aScreenCoordsLocation AttributeLocation = 0
+
+ vertexShaderSource string = `
+ precision highp float;
+ attribute vec2 aScreenCoords;
+ varying vec2 uv;
+
+ void main() {
+ uv = aScreenCoords;
+ gl_Position = vec4(aScreenCoords.xy, 0., 1.);
+ }`
+ fragmentShaderSource string = `
+ precision highp float;
+ varying vec2 uv;
+
+ float F(float a) { return smoothstep(0.0, 0.1, a) * smoothstep(0.4, 0.3, a); }
+
+ void main() {
+ vec2 v = uv * 5.0;
+ gl_FragColor = vec4(0.8, 0.9, 0.6, 1.0) * F(fract(v.x + v.y));
+ }`
+ )
+
+ c := getContext(s)
+
+ var (
+ origProgramID = c.BoundProgram
+ origArrayBufferID = c.BoundBuffers[GLenum_GL_ARRAY_BUFFER]
+ origElementArrayBufferID = c.BoundBuffers[GLenum_GL_ELEMENT_ARRAY_BUFFER]
+ origVertexAttrib = *(c.VertexAttributeArrays[aScreenCoordsLocation])
+ )
+
+ // Generate new unused object IDs.
+ programID := ProgramId(newUnusedID(func(x uint32) bool { _, ok := c.Instances.Programs[ProgramId(x)]; return ok }))
+ vertexShaderID := ShaderId(newUnusedID(func(x uint32) bool { _, ok := c.Instances.Shaders[ShaderId(x)]; return ok }))
+ fragmentShaderID := ShaderId(newUnusedID(func(x uint32) bool {
+ _, ok := c.Instances.Shaders[ShaderId(x)]
+ return ok || ShaderId(x) == vertexShaderID
+ }))
+
+ // 2D vertices positions for a full screen 2D triangle strip.
+ positions := []float32{-1., -1., 1., -1., -1., 1., 1., 1.}
+
+ // Temporarily change rasterizing/blending state and enable VAP 0.
+ undoList := []atom.Atom{}
+ for _, cap := range []GLenum{
+ GLenum_GL_BLEND,
+ GLenum_GL_CULL_FACE,
+ GLenum_GL_DEPTH_TEST,
+ GLenum_GL_SCISSOR_TEST,
+ GLenum_GL_STENCIL_TEST,
+ } {
+ capability := cap
+ if c.Capabilities[capability] {
+ out.Write(atom.NoID, NewGlDisable(capability))
+ undoList = append(undoList, NewGlEnable(capability))
+ }
+ }
+ if !c.VertexAttributeArrays[aScreenCoordsLocation].Enabled {
+ out.Write(atom.NoID, NewGlEnableVertexAttribArray(aScreenCoordsLocation))
+ undoList = append(undoList, NewGlDisableVertexAttribArray(aScreenCoordsLocation))
+ }
+
+ // Create the shader program
+ for _, a := range NewProgram(s.Architecture, d, l, vertexShaderID, fragmentShaderID, programID, vertexShaderSource, fragmentShaderSource) {
+ out.Write(atom.NoID, a)
+ }
+
+ out.Write(atom.NoID, NewGlBindAttribLocation(programID, aScreenCoordsLocation, "aScreenCoords"))
+ out.Write(atom.NoID, NewGlLinkProgram(programID))
+ out.Write(atom.NoID, NewGlUseProgram(programID))
+ out.Write(atom.NoID, NewGlBindBuffer(GLenum_GL_ARRAY_BUFFER, 0))
+ out.Write(atom.NoID, NewGlBindBuffer(GLenum_GL_ELEMENT_ARRAY_BUFFER, 0))
+ out.Write(atom.NoID, NewGlVertexAttribPointer(aScreenCoordsLocation, 2, GLenum_GL_FLOAT, false, 0, memory.Tmp))
+ out.Write(atom.NoID, NewGlDrawArrays(GLenum_GL_TRIANGLE_STRIP, 0, 4).
+ AddRead(atom.Data(s.Architecture, d, l, memory.Tmp, positions)))
+
+ // Restore conditionally changed state.
+ for _, a := range undoList {
+ out.Write(atom.NoID, a)
+ }
+
+ // Restore buffer/vertexAttrib state.
+ if origVertexAttrib.Buffer != 0 || origVertexAttrib.Pointer.Address != 0 {
+ out.Write(atom.NoID, NewGlBindBuffer(GLenum_GL_ARRAY_BUFFER, origVertexAttrib.Buffer))
+ out.Write(atom.NoID, NewGlVertexAttribPointer(aScreenCoordsLocation, int32(origVertexAttrib.Size), origVertexAttrib.Type, origVertexAttrib.Normalized, origVertexAttrib.Stride, origVertexAttrib.Pointer.Pointer))
+ }
+ out.Write(atom.NoID, NewGlBindBuffer(GLenum_GL_ELEMENT_ARRAY_BUFFER, origElementArrayBufferID))
+ out.Write(atom.NoID, NewGlBindBuffer(GLenum_GL_ARRAY_BUFFER, origArrayBufferID))
+
+ // Restore program state.
+ out.Write(atom.NoID, NewGlUseProgram(origProgramID))
+ out.Write(atom.NoID, NewGlDeleteProgram(programID))
+ out.Write(atom.NoID, NewGlDeleteShader(vertexShaderID))
+ out.Write(atom.NoID, NewGlDeleteShader(fragmentShaderID))
+
+ return nil
+}
diff --git a/gfxapi/templates/go_common.tmpl b/gfxapi/templates/go_common.tmpl
index e2600d8..f8c49f2 100644
--- a/gfxapi/templates/go_common.tmpl
+++ b/gfxapi/templates/go_common.tmpl
@@ -457,8 +457,15 @@
*/}}
{{define "Go.MapAssign"}}
{{AssertType $ "MapAssign"}}
- {{if eq $.Operator "="}}{{Template "Go.Read" $.To.Map}}[{{Template "Go.Read" $.To.Index}}] = {{Template "Go.Read" $.Value}}
- {{else}}{{Error "Unsupported MapAssign operator %s" $.Operator}}{{end}}
+ {{if eq $.Operator "="}}
+ {{if IsNull $.Value}}
+ delete({{Template "Go.Read" $.To.Map}}, {{Template "Go.Read" $.To.Index}})
+ {{else}}
+ {{Template "Go.Read" $.To.Map}}[{{Template "Go.Read" $.To.Index}}] = {{Template "Go.Read" $.Value}}
+ {{end}}
+ {{else}}
+ {{Error "Unsupported MapAssign operator %s" $.Operator}}
+ {{end}}
{{end}}
diff --git a/integration/replay/gles/gles_test.go b/integration/replay/gles/gles_test.go
index 2b3ff0a..d18f26f 100644
--- a/integration/replay/gles/gles_test.go
+++ b/integration/replay/gles/gles_test.go
@@ -93,14 +93,15 @@
}
}
-func setBackbuffer(width, height int) atom.Atom {
+func setBackbuffer(width, height int, preserveBuffersOnSwap bool) atom.Atom {
color := gles.GLenum_GL_RGB565
depth := gles.GLenum_GL_DEPTH_COMPONENT16
stencil := gles.GLenum_GL_STENCIL_INDEX8
- return gles.NewBackbufferInfo(int32(width), int32(height), color, depth, stencil, true /* resetViewportScissor */)
+ return gles.NewBackbufferInfo(int32(width), int32(height), color, depth, stencil,
+ true /* resetViewportScissor */, preserveBuffersOnSwap)
}
-func initContext(a device.Architecture, d database.Database, l log.Logger, width, height int) *atom.List {
+func initContext(a device.Architecture, d database.Database, l log.Logger, width, height int, preserveBuffersOnSwap bool) *atom.List {
eglDisplay := p(0x1000)
eglConfig := p(0x2000)
eglShareContext := memory.Nullptr
@@ -113,7 +114,7 @@
gles.NewEglCreateContext(eglDisplay, eglConfig, eglShareContext, p(0x1000000), eglContext).
AddRead(atom.Data(a, d, l, p(0x1000000), eglAttribList)),
gles.NewEglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext, eglTrue),
- setBackbuffer(width, height),
+ setBackbuffer(width, height, preserveBuffersOnSwap),
)
return atoms
}
@@ -122,7 +123,7 @@
d, l := database.NewInMemory(nil), log.Testing(t)
mgr := replay.New(d, l)
device := utils.FindLocalDevice(t, mgr)
- atoms := initContext(device.Info().Architecture(), d, l, 64, 64)
+ atoms := initContext(device.Info().Architecture(), d, l, 64, 64, false)
red := atoms.Add(
gles.NewGlClearColor(1.0, 0.0, 0.0, 1.0),
gles.NewGlClear(gles.GLbitfield_GL_COLOR_BUFFER_BIT),
@@ -157,7 +158,7 @@
device := utils.FindLocalDevice(t, mgr)
a := device.Info().Architecture()
vs, fs, prog, pos := gles.ShaderId(0x10), gles.ShaderId(0x20), gles.ProgramId(0x30), gles.AttributeLocation(0)
- atoms := initContext(a, d, l, 64, 64)
+ atoms := initContext(a, d, l, 64, 64, false)
clear := atoms.Add(
gles.NewGlClearColor(0.0, 1.0, 0.0, 1.0),
gles.NewGlClear(gles.GLbitfield_GL_COLOR_BUFFER_BIT),
@@ -182,14 +183,15 @@
checkColorBuffer(t, ctx, mgr, 64, 64, 0.01, "triangle", triangle)
}
-// TestResizeRenderer checks that backbuffers can be resized without destroying the current context.
+// TestResizeRenderer checks that backbuffers can be resized without destroying
+// the current context.
func TestResizeRenderer(t *testing.T) {
d, l := database.NewInMemory(nil), log.Testing(t)
mgr := replay.New(d, l)
device := utils.FindLocalDevice(t, mgr)
a := device.Info().Architecture()
vs, fs, prog, pos := gles.ShaderId(0x10), gles.ShaderId(0x20), gles.ProgramId(0x30), gles.AttributeLocation(0)
- atoms := initContext(a, d, l, 8, 8) // start with a small backbuffer
+ atoms := initContext(a, d, l, 8, 8, false) // start with a small backbuffer
atoms.Add(gles.NewProgram(a, d, l, vs, fs, prog, simpleVSSource, simpleFSSource)...)
atoms.Add(
gles.NewGlLinkProgram(prog),
@@ -200,7 +202,7 @@
AddRead(atom.Data(a, d, l, p(0x100000), triangleVertices)),
)
triangle := atoms.Add(
- setBackbuffer(64, 64), // Resize just before clearing and drawing.
+ setBackbuffer(64, 64, false), // Resize just before clearing and drawing.
gles.NewGlClearColor(0.0, 0.0, 1.0, 1.0),
gles.NewGlClear(gles.GLbitfield_GL_COLOR_BUFFER_BIT),
gles.NewGlDrawArrays(gles.GLenum_GL_TRIANGLES, 0, 3),
@@ -213,3 +215,30 @@
checkColorBuffer(t, ctx, mgr, 64, 64, 0.01, "triangle_2", triangle)
}
+
+// TestPreserveBuffersOnSwap checks that when the preserveBuffersOnSwap flag is
+// set, the backbuffer is preserved between calls to eglSwapBuffers().
+func TestPreserveBuffersOnSwap(t *testing.T) {
+ d, l := database.NewInMemory(nil), log.Testing(t)
+ mgr := replay.New(d, l)
+ device := utils.FindLocalDevice(t, mgr)
+ a := device.Info().Architecture()
+ atoms := initContext(a, d, l, 64, 64, true)
+ clear := atoms.Add(
+ gles.NewGlClearColor(0.0, 0.0, 1.0, 1.0),
+ gles.NewGlClear(gles.GLbitfield_GL_COLOR_BUFFER_BIT),
+ )
+ swapA := atoms.Add(gles.NewEglSwapBuffers(memory.Nullptr, memory.Nullptr, 1))
+ swapB := atoms.Add(gles.NewEglSwapBuffers(memory.Nullptr, memory.Nullptr, 1))
+ swapC := atoms.Add(gles.NewEglSwapBuffers(memory.Nullptr, memory.Nullptr, 1))
+
+ ctx := &replay.Context{
+ Capture: utils.StoreCapture(t, atoms, d, l).ID,
+ Device: device.ID(),
+ }
+
+ checkColorBuffer(t, ctx, mgr, 64, 64, 0.0, "solid-blue", clear)
+ checkColorBuffer(t, ctx, mgr, 64, 64, 0.0, "solid-blue", swapA)
+ checkColorBuffer(t, ctx, mgr, 64, 64, 0.0, "solid-blue", swapB)
+ checkColorBuffer(t, ctx, mgr, 64, 64, 0.0, "solid-blue", swapC)
+}
diff --git a/replay/batcher.go b/replay/batcher.go
index d9fbf57..0f2d24e 100644
--- a/replay/batcher.go
+++ b/replay/batcher.go
@@ -79,22 +79,7 @@
return fmt.Errorf("Failed to load atom stream (%s): %v", c.Atoms, err)
}
- td := b.device.Info()
-
- transforms := b.context.Generator.ReplayTransforms(
- b.context.Context,
- b.context.Config,
- requests,
- td,
- b.database,
- b.logger)
-
- if config.DebugReplay {
- log.Infof(b.logger, "Replaying %d atoms using transform chain:", len(list.Atoms))
- for i, t := range transforms {
- log.Infof(b.logger, "(%d) %#v", i, t)
- }
- }
+ device := b.device.Info()
architecture := b.device.Info().Architecture()
@@ -102,18 +87,28 @@
if err := func() (err interface{}) {
// Prevent panics from causing GAPIS to fall over.
- // This is temporary, as atoms should return errors instead of causing
- // runtime panics.
+ // This is temporary, as state mutators should return errors instead of
+ // causing runtime panics.
defer func() { err = recover() }()
- transforms.Transform(*list, &adapter{
+
+ out := &adapter{
state: gfxapi.NewState(),
db: b.database,
logger: b.logger,
builder: builder,
- })
- return
+ }
+
+ return b.context.Generator.Replay(
+ b.context.Context,
+ b.context.Config,
+ requests,
+ device,
+ *list,
+ out,
+ b.database,
+ b.logger)
}(); err != nil {
- log.Errorf(b.logger, "Panic raised while transforming atoms for replay: %v", err)
+ log.Errorf(b.logger, "Panic raised while writing atoms for replay: %v", err)
return fmt.Errorf("%v", err)
}
@@ -148,12 +143,12 @@
connection, err := b.device.Connect()
if err != nil {
- return fmt.Errorf("Failed to connect to device %v: %v", td.Name, err)
+ return fmt.Errorf("Failed to connect to device %v: %v", device.Name, err)
}
defer connection.Close()
if config.DebugReplay {
- log.Infof(b.logger, "Sending payload to %v.", td.Name)
+ log.Infof(b.logger, "Sending payload to %v.", device.Name)
}
return executor.Execute(
diff --git a/replay/replay.go b/replay/replay.go
index f535f6d..b68ccaa 100644
--- a/replay/replay.go
+++ b/replay/replay.go
@@ -25,18 +25,19 @@
// Generator is the interface for types that support replay generation.
type Generator interface {
- // ReplayTransforms is called when a replay pass is ready to be sent to the
- // replay device. ReplayTransforms returns an atom transform list that
- // transforms the original, unaltered atom stream into a stream configured for
- // the replay pass. The transforms should satisfy all the specified requests
- // and config.
- ReplayTransforms(
+ // Replay is called when a replay pass is ready to be sent to the replay
+ // device. Replay may filter or transform the list of atoms, satisfying all
+ // the specified requests and config, before outputting the final atom stream
+ // to out.
+ Replay(
ctx Context,
cfg Config,
requests []Request,
device *service.Device,
+ atoms atom.List,
+ out atom.Writer,
db database.Database,
- logger log.Logger) atom.Transforms
+ logger log.Logger) error
}
// Context describes the source capture and replay target information used for