tizen beta release
[framework/web/webkit-efl.git] / Source / WebCore / platform / graphics / efl / LayerWebGLContents.cpp
index 0d81570..462d963 100755 (executable)
 
 #include "GraphicsContext3D.h"
 #include "LayerTextureManager.h"
+#include "Logging.h"
+#include "OwnArrayPtr.h"
+#include "RefPtrCairo.h"
 
 namespace WebCore {
 
-PassOwnPtr<LayerContents> LayerWebGLContents::create(EflLayer* owner)
+PassRefPtr<LayerContents> LayerWebGLContents::create(EflLayer* owner)
 {
-    return adoptPtr(new LayerWebGLContents(owner));
+    return adoptRef(new LayerWebGLContents(owner));
 }
 
 LayerWebGLContents::LayerWebGLContents(EflLayer* owner)
     : LayerContents(owner)
     , m_needToUpdateTexture(false)
+    , m_zoomFactor(1.0)
 {
 }
 
@@ -44,10 +48,37 @@ LayerWebGLContents::~LayerWebGLContents()
 {
 }
 
-void LayerWebGLContents::drawContents(const FloatSize& layerSize, const FloatRect& dirtyRect, float zoomFactor)
+void LayerWebGLContents::releaseResources(LayerTextureManager* manager)
+{
+    // A ownership of WebGL Contents texture is belong to GraphicsContext3D
+    // The texture used by LayerTextureManager for WebGL is borrowed from GraphicsContext3D.
+    // So do not release it here
+
+    m_textureId = 0;
+    m_textureSize = IntSize();
+
+    m_readyToRender = false;
+}
+
+void LayerWebGLContents::drawContents(const FloatRect& contentRect, const FloatRect& dirtyRect, float zoomFactor)
 {
     m_updateRect = IntRect(dirtyRect);
 
+    bool needToRescale = false;
+    IntSize fbSize = m_context->getInternalFramebufferSize();
+    if (m_fbSize != fbSize) {
+        needToRescale = true;
+        m_fbSize = fbSize;
+    }
+    if (m_zoomFactor != zoomFactor) {
+        needToRescale = true;
+        m_zoomFactor = zoomFactor;
+    }
+    if (needToRescale) {
+        m_scaledDrawRect = IntSize(static_cast<int>(m_fbSize.width() * m_zoomFactor)
+            , static_cast<int>(m_fbSize.height() * m_zoomFactor));
+    }
+
     m_needToUpdateTexture = true;
 }
 
@@ -68,6 +99,72 @@ void LayerWebGLContents::updateTexture(LayerTextureManager* manager)
     m_updateRect = IntRect();
 }
 
+void LayerWebGLContents::saveImage(int frame, int tileIndex, const String& dir)
+{
+#if USE(CAIRO)
+    if (m_needToUpdateTexture) {
+        IntRect r = m_owner->screenRect();
+        String fileName = dir + String::format("/%d_%p_%d_html_%d_%d_%d_%d.png", frame, m_owner, tileIndex, r.x(), r.y(), r.width(), r.height());
+
+        unsigned int rowBytes = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, m_fbSize.width());
+        unsigned int totalBytes = rowBytes * m_fbSize.height();
+        OwnArrayPtr<unsigned char> pixels = adoptArrayPtr(new unsigned char[totalBytes]);
+        if (!pixels)
+            return;
+
+        m_context->readRenderingResults(pixels.get(), totalBytes);
+
+        RefPtr<cairo_surface_t> fbCairoSurface = adoptRef(cairo_image_surface_create_for_data(pixels.get()
+                , CAIRO_FORMAT_ARGB32
+                , m_fbSize.width(), m_fbSize.height()
+                , rowBytes));
+        cairo_status_t cairoStatus = cairo_surface_status(fbCairoSurface.get());
+        if (cairoStatus != CAIRO_STATUS_SUCCESS) {
+            LOG(AcceleratedCompositing, "---> RETURN : failed to create cairo_surface_t\n");
+            return;
+        }
+
+        RefPtr<cairo_surface_t> cairoSurface = adoptRef(cairo_image_surface_create(CAIRO_FORMAT_ARGB32
+                , m_scaledDrawRect.width(), m_scaledDrawRect.height()));
+        cairoStatus = cairo_surface_status(cairoSurface.get());
+        if (cairoStatus != CAIRO_STATUS_SUCCESS) {
+            LOG(AcceleratedCompositing, "---> RETURN : failed to create cairo_surface_t\n");
+            return;
+        }
+
+        RefPtr<cairo_t> cairoContext = adoptRef(cairo_create(cairoSurface.get()));
+        cairoStatus = cairo_status(cairoContext.get());
+        if (cairoStatus != CAIRO_STATUS_SUCCESS) {
+            LOG(AcceleratedCompositing, "---> RETURN : failed to create cairo_t\n");
+            return;
+        }
+
+        cairo_matrix_t resultMat;
+        cairo_matrix_t t1, t2;
+        cairo_matrix_t s;
+        cairo_matrix_t flip;
+
+        cairo_matrix_init_identity(&resultMat);
+        cairo_matrix_init_translate(&t1, m_scaledDrawRect.width() * 0.5, m_scaledDrawRect.height() * 0.5);
+        cairo_matrix_init_scale(&s, m_zoomFactor, m_zoomFactor);
+        cairo_matrix_init(&flip, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0);
+        cairo_matrix_init_translate(&t2, -m_fbSize.width() * 0.5, -m_fbSize.height() * 0.5);
+
+        cairo_matrix_multiply(&resultMat, &resultMat, &t2);
+        cairo_matrix_multiply(&resultMat, &resultMat, &flip);
+        cairo_matrix_multiply(&resultMat, &resultMat, &s);
+        cairo_matrix_multiply(&resultMat, &resultMat, &t1);
+
+        cairo_set_matrix(cairoContext.get(), &resultMat);
+        cairo_set_source_surface(cairoContext.get(), fbCairoSurface.get(), 0, 0);
+        cairo_set_operator (cairoContext.get(), CAIRO_OPERATOR_SOURCE);
+        cairo_paint(cairoContext.get());
+
+        cairo_surface_write_to_png(cairoSurface.get(), fileName.utf8().data());
+    }
+#endif
+}
+
 } // namespace WebCore
 
 #endif