Ok, since there were no responses to my question i will share what I've got.
First of all I am using OpenGL ES 2.0.
1) I draw two triangles to cover whole screen like this

to store Vertices and triangles I use following structs (Color value is not used in my case):
typedef struct {
float Position[3];
float Color[4];
float TexCoord[2];
} Vertex;
const Vertex Vertices[] = {
{{1, -1, 0}, {1, 0, 0, 1}, {1, 0}},
{{1, 1, 0}, {0, 1, 0, 1}, {1, 1}},
{{-1, 1, 0}, {0, 0, 1, 1}, {0, 1}},
{{-1, -1, 0}, {0, 0, 0, 1}, {0, 0}}
};
const GLubyte Indices[] = {
0, 1, 2,
2, 3, 0
};
2) After that done I wait for whole remote screen to load image and than I set that image of whole screen as texture using following code:
-(void)setupTextureFromCGImage:(CGImageRef)imageRef{
NSDictionary * options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:_snapshot.isImageMirrored],
GLKTextureLoaderOriginBottomLeft,
nil];
NSError * error;
GLKTextureInfo * info = [GLKTextureLoader textureWithCGImage:imageRef options:options error:&error];
if (info == nil) {
NSLog(@"Error loading file: %@", [error localizedDescription]);
return;
}
self.effect.texture2d0.name = info.name;
self.effect.texture2d0.enabled = true;
_bigTexture = info.name;
glBindTexture(GL_TEXTURE_2D, self.effect.texture2d0.name);
}
This code uses GLKit's GLKTextureLoader, however this can be simply replaced with glteximage2d().
After that view looks similar to this:

3) When the update received we need image of update and rect to know which part to update:
-(void)loadSubImageTextureImageBuffer:(const char *)buffer inRect:(CGRect)rect
{
CGRect rectGL = rect;
rectGL.origin.y = _snapshot.imageRect.size.height - (rectGL.origin.y + rectGL.size.height);// convert coordinates from UIView's upper left to OpenGL's lower left
glTexSubImage2D(GL_TEXTURE_2D,
0,
rectGL.origin.x,
rectGL.origin.y,
rectGL.size.width,
rectGL.size.height,
GL_BGRA,
GL_UNSIGNED_BYTE,
buffer);
}
For drawing I use custom shaders not GLKView, they do nothing but mapping texture to vertices.
OpenGL drawing works faster then CATiledLayer, not extremely but still. There are some few glitches which I will investigate in the future.
Hope this will be useful for somebody. If you need some more details feel free to contact me
haawaplus@gmail.com
P.S
For now I paused my CATiledLayer -> OpenGL ES investigation since i got some other work to do but I will update my answer when I will return to OpenGL.