Pass atoms directly to the replay.Generator...

... instead of handing back a transform list.
This will allow the generator to make better decisions on the atoms it is
dealing with, and could greatly simplify the logic.

Change-Id: I6ef161fc7f25c5f60f2b12f7a3c10bff4545e98c
diff --git a/gfxapi/gles/replay.go b/gfxapi/gles/replay.go
index b93d934..5fe239e 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,
+	atoms atom.List,
+	out atom.Writer,
 	db database.Database,
-	logger log.Logger) atom.Transforms {
+	logger log.Logger) error {
 
 	transforms := atom.Transforms{}
 
@@ -119,7 +122,7 @@
 		precisionStrip(device, db, logger),
 		halfFloatOESToHalfFloatARB(device))
 
-	if c, ok := config.(drawConfig); ok && c.wireframe {
+	if c, ok := cfg.(drawConfig); ok && c.wireframe {
 		transforms.Add(wireframe(db, logger))
 	}
 
@@ -130,7 +133,16 @@
 		logger: logger,
 	})
 
-	return transforms
+	if config.DebugReplay {
+		log.Infof(logger, "Replaying %d atoms using transform chain:", len(atoms.Atoms))
+		for i, t := range transforms {
+			log.Infof(logger, "(%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/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