http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/page/render_page.cpp
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/page/render_page.cpp 
b/weex_core/Source/core/render/page/render_page.cpp
new file mode 100644
index 0000000..c518956
--- /dev/null
+++ b/weex_core/Source/core/render/page/render_page.cpp
@@ -0,0 +1,631 @@
+#include <core/parser/dom_parser.h>
+#include <core/render/action/render_action_add_element.h>
+#include <core/render/action/render_action_remove_element.h>
+#include <core/render/action/render_action_move_element.h>
+#include <core/render/action/render_action_createbody.h>
+#include <core/render/action/render_action_update_style.h>
+#include <core/render/action/render_action_update_attr.h>
+#include <core/render/action/render_action_layout.h>
+#include <core/render/action/render_action_createfinish.h>
+#include <core/layout/layout.h>
+#include <android/base/string/string_utils.h>
+#include <core/moniter/render_performance.h>
+#include <core/config/core_environment.h>
+#include <base/ViewUtils.h>
+#include <core/render/action/render_action_add_event.h>
+#include <core/render/action/render_action_remove_event.h>
+#include <core/css/constants_value.h>
+#include "render_page.h"
+#include "core/render/manager/render_manager.h"
+#include "core/render/node/render_object.h"
+
+namespace WeexCore {
+
+  static bool splitScreenRendering = false;
+
+  RenderPage::RenderPage(std::string pageId) {
+
+#if RENDER_LOG
+    LOGD("[RenderPage] new RenderPage >>>> pageId: %s", pageId.c_str());
+#endif
+
+    mPageId = pageId;
+    mWXCorePerformance = new RenderPerformance();
+    mViewPortWidth = kDefaultViewPortWidth;
+    renderPageSize.first = WXCoreEnvironment::getInstance()->DeviceWidth();
+    renderPageSize.second = NAN;
+  }
+
+  RenderPage::~RenderPage() {
+
+#if RENDER_LOG
+    LOGD("[RenderPage] Delete RenderPage >>>> pageId: %s", mPageId.c_str());
+#endif
+
+    mRenderObjectRegisterMap.clear();
+
+    if (render_root != nullptr) {
+      delete render_root;
+      render_root = nullptr;
+    }
+
+    if (mWXCorePerformance != nullptr) {
+      delete mWXCorePerformance;
+      mWXCorePerformance = nullptr;
+    }
+  }
+
+  void RenderPage::CalculateLayout() {
+    if (render_root == nullptr || !render_root->ViewInit())
+      return;
+
+#if RENDER_LOG
+    LOGD("[RenderPage] CalculateLayout >>>> pageId: %s", mPageId.c_str());
+#endif
+
+    long long startTime = getCurrentTime();
+    render_root->LayoutBefore();
+    render_root->calculateLayout(renderPageSize);
+    render_root->LayoutAfter();
+    CssLayoutTime(getCurrentTime() - startTime);
+
+    if (splitScreenRendering) {
+      if (mAlreadyCreateFinish) {
+        TraverseTree(render_root, 0);
+      } else {
+        float deviceHeight = WXCoreEnvironment::getInstance()->DeviceHeight();
+        float deviceWidth = WXCoreEnvironment::getInstance()->DeviceWidth();
+        float radio = deviceWidth / (mViewPortWidth * 
kLayoutFirstScreenOverflowRadio);
+
+        switch (render_root->getFlexDirection()) {
+          case kFlexDirectionColumn:
+          case kFlexDirectionColumnReverse:
+            if (render_root->getLargestMainSize() * radio > deviceHeight / 3) {
+              TraverseTree(render_root, 0);
+            }
+            break;
+          case kFlexDirectionRow:
+          case kFlexDirectionRowReverse:
+          default:
+            if (render_root->getLargestMainSize() * radio > deviceWidth / 3) {
+              TraverseTree(render_root, 0);
+            }
+            break;
+        }
+      }
+    } else {
+      TraverseTree(render_root, 0);
+    }
+  }
+
+  void RenderPage::TraverseTree(RenderObject *render,int index) {
+
+    if (render == nullptr)
+      return;
+
+    if (render->hasNewLayout()) {
+      SendLayoutAction(render, index);
+      render->setHasNewLayout(false);
+    }
+
+    for(auto it = render->ChildListIterBegin(); it != 
render->ChildListIterEnd(); it++) {
+      RenderObject* child = static_cast<RenderObject*>(*it);
+      if (child != nullptr) {
+        TraverseTree(child, it-render->ChildListIterBegin());
+      }
+    }
+  }
+
+  bool RenderPage::CreateRootRender(RenderObject *root) {
+
+    if (root == nullptr)
+      return false;
+
+    long long startTime = getCurrentTime();
+    SetRootRenderObject(root);
+
+    if (isnan(render_root->getStyleWidth())) {
+      render_root->setStyleWidthLevel(FALLBACK_STYLE);
+      if (GetRenderContainerWidthWrapContent())
+        render_root->setStyleWidthToNAN();
+      else
+        
render_root->setStyleWidth(WXCoreEnvironment::getInstance()->DeviceWidth(), 
false);
+    } else {
+      render_root->setStyleWidthLevel(CSS_STYLE);
+    }
+    PushRenderToRegisterMap(root);
+
+    BuildRenderTreeTime(getCurrentTime() - startTime);
+    SendCreateBodyAction(root);
+    return true;
+  }
+
+  void RenderPage::SetRootRenderObject(RenderObject *root) {
+    if (root != nullptr) {
+      render_root = root;
+      render_root->MarkRootRender();
+    }
+  }
+
+  bool RenderPage::AddRenderObject(const std::string &parentRef, int 
insertPosition, RenderObject *child) {
+    long long startTime = getCurrentTime();
+    RenderObject *parent = GetRenderObject(parentRef);
+    if (parent == nullptr || child == nullptr) {
+      return false;
+    }
+
+    // add child to Render Tree
+    insertPosition = parent->AddRenderObject(insertPosition, child);
+    if (insertPosition < -1) {
+      return false;
+    }
+
+    PushRenderToRegisterMap(child);
+    BuildRenderTreeTime(getCurrentTime() - startTime);
+    SendAddElementAction(child, parent, insertPosition);
+
+    Batch();
+    return true;
+  }
+
+  bool RenderPage::RemoveRenderObject(const std::string &ref) {
+    long long startTime = getCurrentTime();
+    RenderObject *child = GetRenderObject(ref);
+    if (child == nullptr)
+      return false;
+
+    RenderObject *parent = child->GetParentRender();
+    if (parent == nullptr)
+      return false;
+
+    parent->RemoveRenderObject(child);
+
+    RemoveRenderFromRegisterMap(child);
+    delete child;
+
+    BuildRenderTreeTime(getCurrentTime() - startTime);
+
+    SendRemoveElementAction(ref);
+    return true;
+  }
+
+  bool RenderPage::MoveRenderObject(const std::string &ref, const std::string 
&parentRef, int index) {
+    long long startTime = getCurrentTime();
+
+    RenderObject *child = GetRenderObject(ref);
+    if (child == nullptr)
+      return false;
+
+    RenderObject *oldParent = child->GetParentRender();
+    RenderObject *newParent = GetRenderObject(parentRef);
+    if (oldParent == nullptr || newParent == nullptr)
+      return false;
+
+    if (oldParent->Ref() == newParent->Ref()) {
+      if (oldParent->IndexOf(child) < 0) {
+        return false;
+      } else if (oldParent->IndexOf(child) == index) {
+        return false;
+      } else if (oldParent->IndexOf(child) < index) {
+        index = index - 1;
+      }
+    }
+
+    child->getParent()->removeChild(child);
+    newParent->addChildAt(child, index);
+
+    BuildRenderTreeTime(getCurrentTime() - startTime);
+
+    SendMoveElementAction(ref, parentRef, index);
+    return true;
+  }
+
+  bool RenderPage::UpdateStyle(const std::string &ref, 
std::vector<std::pair<std::string, std::string>> *src) {
+    long long startTime = getCurrentTime();
+    RenderObject *render = GetRenderObject(ref);
+    if (render == nullptr || src == nullptr || src->empty())
+      return false;
+
+    std::vector<std::pair<std::string, std::string>> *style = nullptr;
+    std::vector<std::pair<std::string, std::string>> *margin = nullptr;
+    std::vector<std::pair<std::string, std::string>> *padding = nullptr;
+    std::vector<std::pair<std::string, std::string>> *border = nullptr;
+
+    bool flag = false;
+
+    int result = 
Bridge_Impl_Android::getInstance()->callHasTransitionPros(mPageId.c_str(), 
ref.c_str(), src);
+
+    if (result == 1) {
+      BuildRenderTreeTime(getCurrentTime() - startTime);
+      SendUpdateStyleAction(render, src, margin, padding, border);
+    } else {
+      for (auto iter = src->begin(); iter != src->end(); iter++) {
+        switch (render->UpdateStyle((*iter).first, (*iter).second)) {
+          case kTypeStyle:
+            if (style == nullptr) {
+              style = new std::vector<std::pair<std::string, std::string>>();
+            }
+            style->insert(style->end(), (*iter));
+            flag = true;
+            break;
+          case kTypeMargin:
+            if (margin == nullptr) {
+              margin = new std::vector<std::pair<std::string, std::string>>();
+            }
+            render->UpdateStyle((*iter).first,
+                                (*iter).second,
+                                0,
+                                [=, &flag](float foo) {
+                                  (*iter).second = std::to_string(foo),
+                                      margin->insert(margin->end(), (*iter)),
+                                  flag = true;
+                                });
+            break;
+          case kTypePadding:
+            if (padding == nullptr) {
+              padding = new std::vector<std::pair<std::string, std::string>>();
+            }
+            render->UpdateStyle((*iter).first,
+                                (*iter).second,
+                                0,
+                                [=, &flag](float foo) {
+                                  (*iter).second = std::to_string(foo),
+                                      padding->insert(padding->end(), (*iter)),
+                                  flag = true;
+                                });
+            break;
+          case kTypeBorder:
+            if (border == nullptr) {
+              border = new std::vector<std::pair<std::string, std::string>>();
+            }
+            render->UpdateStyle((*iter).first,
+                                (*iter).second,
+                                0,
+                                [=, &flag](float foo) {
+                                  (*iter).second = std::to_string(foo),
+                                      border->insert(border->end(), (*iter)),
+                                  flag = true;
+                                });
+            break;
+        }
+      }
+    }
+
+    BuildRenderTreeTime(getCurrentTime() - startTime);
+
+    if (style != nullptr || margin != nullptr || padding != nullptr || border 
!= nullptr)
+      SendUpdateStyleAction(render, style, margin, padding, border);
+
+    Batch();
+
+    if (src != nullptr) {
+      src->clear();
+      src->shrink_to_fit();
+      delete src;
+      src = nullptr;
+    }
+
+    if (style != nullptr) {
+      style->clear();
+      style->shrink_to_fit();
+      delete style;
+      style = nullptr;
+    }
+
+    if (margin != nullptr) {
+      margin->clear();
+      margin->shrink_to_fit();
+      delete margin;
+      margin = nullptr;
+    }
+
+    if (padding != nullptr) {
+      padding->clear();
+      padding->shrink_to_fit();
+      delete padding;
+      padding = nullptr;
+    }
+
+    if (border != nullptr) {
+      border->clear();
+      border->shrink_to_fit();
+      delete border;
+      border = nullptr;
+    }
+
+    return flag;
+  }
+
+  bool RenderPage::UpdateAttr(const std::string &ref, 
std::vector<std::pair<std::string, std::string>> *attrs) {
+    long long startTime = getCurrentTime();
+    RenderObject *render = GetRenderObject(ref);
+    if (render == nullptr || attrs == nullptr || attrs->empty())
+      return false;
+
+    SendUpdateAttrAction(render, attrs);
+
+    for (auto iter = attrs->cbegin(); iter != attrs->cend(); iter++) {
+      render->UpdateAttr((*iter).first, (*iter).second);
+    }
+
+    if (attrs != nullptr) {
+      attrs->clear();
+      attrs->shrink_to_fit();
+      delete attrs;
+      attrs = nullptr;
+    }
+
+    return true;
+  }
+
+  void RenderPage::SetDefaultHeightAndWidthIntoRootRender(const float 
defaultWidth,
+                                                          const float 
defaultHeight,
+                                                          const bool 
isWidthWrapContent, const bool isHeightWrapContent) {
+    renderPageSize.first = defaultWidth;
+    renderPageSize.second = defaultHeight;
+    if (render_root->getStyleWidthLevel() >= INSTANCE_STYLE) {
+      render_root->setStyleWidthLevel(INSTANCE_STYLE);
+      if (isWidthWrapContent) {
+        SetRenderContainerWidthWrapContent(true);
+        render_root->setStyleWidthToNAN();
+        renderPageSize.first = NAN;
+      } else {
+        render_root->setStyleWidth(defaultWidth, true);
+      }
+      updateDirty(true);
+    }
+
+    if (render_root->getStyleHeightLevel() >= INSTANCE_STYLE) {
+      if(!isHeightWrapContent) {
+        render_root->setStyleHeightLevel(INSTANCE_STYLE);
+        render_root->setStyleHeight(defaultHeight);
+        updateDirty(true);
+      }
+    }
+
+    Batch();
+  }
+
+  bool RenderPage::AddEvent(const std::string &ref, const std::string &event) {
+    long long startTime = getCurrentTime();
+    RenderObject *render = GetRenderObject(ref);
+    if (render == nullptr)
+      return false;
+
+    render->AddEvent(event);
+    BuildRenderTreeTime(getCurrentTime() - startTime);
+
+    render_action *action = new RenderActionAddEvent(mPageId, ref, event);
+    PostRenderAction(action);
+    return true;
+  }
+
+  bool RenderPage::RemoveEvent(const std::string &ref, const std::string 
&event) {
+    long long startTime = getCurrentTime();
+    RenderObject *render = GetRenderObject(ref);
+    if (render == nullptr)
+      return false;
+
+    render->RemoveEvent(event);
+    BuildRenderTreeTime(getCurrentTime() - startTime);
+
+    render_action *action = new RenderActionRemoveEvent(mPageId, ref, event);
+    PostRenderAction(action);
+    return true;
+  }
+
+  bool RenderPage::CreateFinish() {
+    if (render_root == nullptr) {
+      return false;
+    }
+    mAlreadyCreateFinish = true;
+    Batch();
+    SendCreateFinishAction();
+    return true;
+  }
+
+  void RenderPage::LayoutImmediately() {
+    if(isDirty() && useVSync){
+      CalculateLayout();
+      needLayout.store(false);
+      updateDirty(false);
+    }
+  }
+
+  void RenderPage::PostRenderAction(render_action *action) {
+    if (action != nullptr) {
+      action->ExecuteAction();
+    }
+  }
+
+  void RenderPage::PushRenderToRegisterMap(RenderObject *render) {
+    if (render == nullptr)
+      return;
+
+    std::string ref = render->Ref();
+    mRenderObjectRegisterMap.insert(std::pair<std::string, RenderObject 
*>(ref, render));
+
+    for(auto it = render->ChildListIterBegin(); it != 
render->ChildListIterEnd(); it++) {
+      RenderObject* child = static_cast<RenderObject*>(*it);
+      if (child != nullptr) {
+        PushRenderToRegisterMap(child);
+      }
+    }
+  }
+
+  void RenderPage::RemoveRenderFromRegisterMap(RenderObject *render) {
+    if (render == nullptr)
+      return;
+
+    mRenderObjectRegisterMap.erase(render->Ref());
+
+    for(auto it = render->ChildListIterBegin(); it != 
render->ChildListIterEnd(); it++) {
+      RenderObject* child = static_cast<RenderObject*>(*it);
+      if (child != nullptr) {
+        RemoveRenderFromRegisterMap(child);
+      }
+    }
+  }
+
+  void RenderPage::SendCreateBodyAction(RenderObject *render) {
+    if (render == nullptr)
+      return;
+
+    render_action *action = new RenderActionCreateBody(PageId(), render);
+    PostRenderAction(action);
+
+    Index i = 0;
+    for(auto it = render->ChildListIterBegin(); it != 
render->ChildListIterEnd(); it++) {
+      RenderObject* child = static_cast<RenderObject*>(*it);
+      if (child != nullptr) {
+        SendAddElementAction(child, render, i);
+      }
+      ++i;
+    }
+  }
+
+  void RenderPage::SendAddElementAction(RenderObject *child, RenderObject 
*parent, int index) {
+    if (child == nullptr || parent == nullptr)
+      return;
+
+    render_action *action = new RenderActionAddElement(PageId(), child, 
parent, index);
+    PostRenderAction(action);
+
+    Index i = 0;
+    for(auto it = child->ChildListIterBegin(); it != 
child->ChildListIterEnd(); it++) {
+      RenderObject* grandson = static_cast<RenderObject*>(*it);
+      if (grandson != nullptr) {
+        SendAddElementAction(grandson, child, i);
+      }
+      ++i;
+    }
+  }
+
+  void RenderPage::SendRemoveElementAction(const std::string &ref) {
+    render_action *action = new RenderActionRemoveElement(PageId(), ref);
+    PostRenderAction(action);
+  }
+
+  void RenderPage::SendMoveElementAction(const std::string &ref, const 
std::string &parentRef, int index) {
+    render_action *action = new RenderActionMoveElement(PageId(), ref, 
parentRef, index);
+    PostRenderAction(action);
+  }
+
+  void RenderPage::SendLayoutAction(RenderObject *render, int index) {
+    if (render == nullptr)
+      return;
+
+    render_action *action = new RenderActionLayout(PageId(), render, index);
+    PostRenderAction(action);
+  }
+
+  void RenderPage::SendUpdateStyleAction(RenderObject *render,
+                                         std::vector<std::pair<std::string, 
std::string>> *style,
+                                         std::vector<std::pair<std::string, 
std::string>> *margin,
+                                         std::vector<std::pair<std::string, 
std::string>> *padding,
+                                         std::vector<std::pair<std::string, 
std::string>> *border) {
+    render_action *action = new RenderActionUpdateStyle(PageId(), 
render->Ref(), style, margin, padding, border);
+    PostRenderAction(action);
+  }
+
+  void RenderPage::SendUpdateAttrAction(RenderObject *render,
+                                        std::vector<std::pair<std::string, 
std::string>> *attrs) {
+    render_action *action = new RenderActionUpdateAttr(PageId(), 
render->Ref(), attrs);
+    PostRenderAction(action);
+  }
+
+  void RenderPage::SendCreateFinishAction() {
+    render_action *action = new RenderActionCreateFinish(PageId());
+    PostRenderAction(action);
+  }
+
+  void RenderPage::JniCallTime(const long long &time) {
+    if (mWXCorePerformance != nullptr)
+      mWXCorePerformance->jniCallTime += time;
+  }
+
+  void RenderPage::CssLayoutTime(const long long &time) {
+    if (mWXCorePerformance != nullptr)
+      mWXCorePerformance->cssLayoutTime += time;
+  }
+
+  void RenderPage::AddEventActionJNITime(const long long &time) {
+    if (mWXCorePerformance != nullptr)
+      mWXCorePerformance->addEventActionJNITime += time;
+  }
+
+  void RenderPage::RemoveEventActionJNITime(const long long &time) {
+    if (mWXCorePerformance != nullptr)
+      mWXCorePerformance->removeEventActionJNITime += time;
+  }
+
+  void RenderPage::AddElementActionJNITime(const long long &time) {
+    if (mWXCorePerformance != nullptr)
+      mWXCorePerformance->addElementActionJNITime += time;
+  }
+
+  void RenderPage::LayoutActionJniTime(const long long &time) {
+    if (mWXCorePerformance != nullptr)
+      mWXCorePerformance->layoutActionJniTime += time;
+  }
+
+  void RenderPage::ParseJsonTime(const long long &time) {
+    if (mWXCorePerformance != nullptr)
+      mWXCorePerformance->parseJsonTime += time;
+  }
+
+  void RenderPage::BuildRenderTreeTime(const long long &time) {
+    if (mWXCorePerformance != nullptr)
+      mWXCorePerformance->buildRenderObjectTime += time;
+  }
+
+  void RenderPage::CreateJMapJNITime(const long long &time) {
+    if (mWXCorePerformance != nullptr)
+      mWXCorePerformance->createJMapJNITime += time;
+  }
+
+  void RenderPage::CallBridgeTime(const long long &time) {
+    if (mWXCorePerformance != nullptr)
+      mWXCorePerformance->jniCallBridgeTime += time;
+  }
+
+  int RenderPage::PrintFirstScreenLog() {
+    if (mWXCorePerformance != nullptr)
+      return mWXCorePerformance->PrintPerformanceLog(onFirstScreen);
+    return 0;
+  }
+
+  int RenderPage::PrintRenderSuccessLog() {
+    if (mWXCorePerformance != nullptr)
+      return mWXCorePerformance->PrintPerformanceLog(onRenderSuccess);
+    return 0;
+  }
+
+  void RenderPage::Batch() {
+    if ((useVSync && needLayout.load()) || !useVSync) {
+      CalculateLayout();
+      needLayout.store(false);
+      updateDirty(false);
+    }
+  }
+
+  void RenderPage::OnRenderPageInit() {
+
+  }
+
+  void RenderPage::OnRenderProcessStart() {
+
+  }
+
+  void RenderPage::OnRenderProcessExited() {
+
+  }
+
+  void RenderPage::OnRenderProcessGone() {
+
+  }
+
+  void RenderPage::OnRenderPageClose() {
+
+  }
+} //namespace WeexCore

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/page/render_page.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/page/render_page.h 
b/weex_core/Source/core/render/page/render_page.h
new file mode 100644
index 0000000..d5df3ba
--- /dev/null
+++ b/weex_core/Source/core/render/page/render_page.h
@@ -0,0 +1,180 @@
+#ifndef RenderPage_H
+#define RenderPage_H
+
+#include <vector>
+#include <string>
+#include <map>
+#include <jni.h>
+#include <cmath>
+
+namespace WeexCore {
+
+  constexpr float kLayoutFirstScreenOverflowRadio = 1.2f;
+
+  class render_action;
+
+  class RenderObject;
+
+  class RenderPerformance;
+
+  class RenderPage {
+
+  private:
+
+    void TraverseTree(RenderObject *render, int index);
+
+    void PushRenderToRegisterMap(RenderObject *render);
+
+    void RemoveRenderFromRegisterMap(RenderObject *render);
+
+    void SendCreateBodyAction(RenderObject *render);
+
+    void SendAddElementAction(RenderObject *child, RenderObject *parent, int 
index);
+
+    void SendRemoveElementAction(const std::string &ref);
+
+    void SendMoveElementAction(const std::string &ref, const std::string 
&parentRef, int index);
+
+    void SendLayoutAction(RenderObject *render, int index);
+
+    void
+    SendUpdateStyleAction(RenderObject *render,
+                          std::vector<std::pair<std::string, std::string>> 
*style,
+                          std::vector<std::pair<std::string, std::string>> 
*margin,
+                          std::vector<std::pair<std::string, std::string>> 
*padding,
+                          std::vector<std::pair<std::string, std::string>> 
*border);
+
+    void SendUpdateAttrAction(RenderObject *render, 
std::vector<std::pair<std::string, std::string>> *attrs);
+
+    void SendCreateFinishAction();
+
+    void PostRenderAction(render_action *action);
+
+  public:
+    static constexpr bool useVSync = true;
+    std::atomic_bool needLayout{false};
+    std::atomic_bool hasForeLayoutAction{false};
+    RenderPage(std::string pageId);
+
+    ~RenderPage();
+
+    void CalculateLayout();
+
+    bool CreateRootRender(RenderObject *root);
+
+    bool AddRenderObject(const std::string &parentRef, int insertPosiotn, 
RenderObject *child);
+
+    bool RemoveRenderObject(const std::string &ref);
+
+    bool MoveRenderObject(const std::string &ref, const std::string 
&parentRef, int index);
+
+    bool UpdateStyle(const std::string &ref, 
std::vector<std::pair<std::string, std::string>> *styles);
+
+    bool UpdateAttr(const std::string &ref, std::vector<std::pair<std::string, 
std::string>> *attrs);
+
+    void SetDefaultHeightAndWidthIntoRootRender(const float defaultWidth, 
const float defaultHeight, const bool isWidthWrapContent, const bool 
isHeightWrapContent);
+
+    bool AddEvent(const std::string &ref, const std::string &event);
+
+    bool RemoveEvent(const std::string &ref, const std::string &event);
+
+    bool CreateFinish();
+
+    void Batch();
+
+    void JniCallTime(const long long &time);
+
+    void CssLayoutTime(const long long &time);
+
+    void AddEventActionJNITime(const long long &time);
+
+    void RemoveEventActionJNITime(const long long &time);
+
+    void AddElementActionJNITime(const long long &time);
+
+    void LayoutActionJniTime(const long long &time);
+
+    void ParseJsonTime(const long long &time);
+
+    void BuildRenderTreeTime(const long long &time);
+
+    void CreateJMapJNITime(const long long &time);
+
+    void CallBridgeTime(const long long &time);
+
+    int PrintFirstScreenLog();
+
+    int PrintRenderSuccessLog();
+
+    void LayoutImmediately();
+
+    inline RenderObject *GetRenderObject(const std::string &ref) {
+        std::map<std::string, RenderObject *>::iterator iter = 
mRenderObjectRegisterMap.find(ref);
+        if (iter != mRenderObjectRegisterMap.end()) {
+            return iter->second;
+        } else {
+            return nullptr;
+        }
+    }
+
+    void SetRootRenderObject(RenderObject *root);
+
+    inline RenderObject * GetRootRenderObject() const {
+      return render_root;
+    }
+
+    inline std::string PageId() {
+      return mPageId;
+    }
+
+    inline float ViewPortWidth() const {
+      return mViewPortWidth;
+    }
+
+    inline void SetViewPortWidth(float viewPortWidth) {
+      this->mViewPortWidth = viewPortWidth;
+    }
+
+    inline bool isDirty(){
+      return dirty.load();
+    }
+
+    inline void updateDirty(bool dirty){
+      this->dirty.store(dirty);
+    }
+
+    inline void SetRenderContainerWidthWrapContent(bool wrap) {
+      this->isRenderContainerWidthWrapContent.store(wrap);
+    }
+
+    inline bool GetRenderContainerWidthWrapContent() {
+      return isRenderContainerWidthWrapContent.load();
+    }
+
+    // ****** Life Cycle ****** //
+
+    void OnRenderPageInit();
+
+    void OnRenderProcessStart();
+
+    void OnRenderProcessExited();
+
+    void OnRenderProcessGone();
+
+    void OnRenderPageClose();
+
+  private:
+    bool mAlreadyCreateFinish = false;
+    float mViewPortWidth;
+    RenderObject *render_root = nullptr;
+    std::string mPageId;
+    std::pair<float,float> renderPageSize;
+    std::map<std::string, RenderObject *> mRenderObjectRegisterMap;
+    RenderPerformance *mWXCorePerformance;
+    std::atomic_bool dirty{true};
+    std::atomic_bool isRenderContainerWidthWrapContent{false};
+    std::atomic_bool isRenderContainerHeightWrapContent{false};
+  };
+}
+
+#endif //RenderManager_h
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/rapidjson/allocators.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/rapidjson/allocators.h 
b/weex_core/Source/rapidjson/allocators.h
new file mode 100644
index 0000000..655f4a3
--- /dev/null
+++ b/weex_core/Source/rapidjson/allocators.h
@@ -0,0 +1,271 @@
+// Tencent is pleased to support the open source community by making RapidJSON 
available.
+// 
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All 
rights reserved.
+//
+// Licensed under the MIT License (the "License"); you may not use this file 
except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// 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.
+
+#ifndef RAPIDJSON_ALLOCATORS_H_
+#define RAPIDJSON_ALLOCATORS_H_
+
+#include "rapidjson.h"
+
+RAPIDJSON_NAMESPACE_BEGIN
+
+///////////////////////////////////////////////////////////////////////////////
+// Allocator
+
+/*! \class rapidjson::Allocator
+    \brief Concept for allocating, resizing and freeing memory block.
+    
+    Note that Malloc() and Realloc() are non-static but Free() is static.
+    
+    So if an allocator need to support Free(), it needs to put its pointer in 
+    the header of memory block.
+
+\code
+concept Allocator {
+    static const bool kNeedFree;    //!< Whether this allocator needs to call 
Free().
+
+    // Allocate a memory block.
+    // \param size of the memory block in bytes.
+    // \returns pointer to the memory block.
+    void* Malloc(size_t size);
+
+    // Resize a memory block.
+    // \param originalPtr The pointer to current memory block. Null pointer is 
permitted.
+    // \param originalSize The current size in bytes. (Design issue: since 
some allocator may not book-keep this, explicitly pass to it can save memory.)
+    // \param newSize the new size in bytes.
+    void* Realloc(void* originalPtr, size_t originalSize, size_t newSize);
+
+    // Free a memory block.
+    // \param pointer to the memory block. Null pointer is permitted.
+    static void Free(void *ptr);
+};
+\endcode
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+// CrtAllocator
+
+//! C-runtime library allocator.
+/*! This class is just wrapper for standard C library memory routines.
+    \note implements Allocator concept
+*/
+class CrtAllocator {
+public:
+    static const bool kNeedFree = true;
+    void* Malloc(size_t size) { 
+        if (size) //  behavior of malloc(0) is implementation defined.
+            return std::malloc(size);
+        else
+            return NULL; // standardize to returning NULL.
+    }
+    void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
+        (void)originalSize;
+        if (newSize == 0) {
+            std::free(originalPtr);
+            return NULL;
+        }
+        return std::realloc(originalPtr, newSize);
+    }
+    static void Free(void *ptr) { std::free(ptr); }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// MemoryPoolAllocator
+
+//! Default memory allocator used by the parser and DOM.
+/*! This allocator allocate memory blocks from pre-allocated memory chunks. 
+
+    It does not free memory blocks. And Realloc() only allocate new memory.
+
+    The memory chunks are allocated by BaseAllocator, which is CrtAllocator by 
default.
+
+    User may also supply a buffer as the first chunk.
+
+    If the user-buffer is full then additional chunks are allocated by 
BaseAllocator.
+
+    The user-buffer is not deallocated by this allocator.
+
+    \tparam BaseAllocator the allocator type for allocating memory chunks. 
Default is CrtAllocator.
+    \note implements Allocator concept
+*/
+template <typename BaseAllocator = CrtAllocator>
+class MemoryPoolAllocator {
+public:
+    static const bool kNeedFree = false;    //!< Tell users that no need to 
call Free() with this allocator. (concept Allocator)
+
+    //! Constructor with chunkSize.
+    /*! \param chunkSize The size of memory chunk. The default is 
kDefaultChunkSize.
+        \param baseAllocator The allocator for allocating memory chunks.
+    */
+    MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, 
BaseAllocator* baseAllocator = 0) : 
+        chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(0), 
baseAllocator_(baseAllocator), ownBaseAllocator_(0)
+    {
+    }
+
+    //! Constructor with user-supplied buffer.
+    /*! The user buffer will be used firstly. When it is full, memory pool 
allocates new chunk with chunk size.
+
+        The user buffer will not be deallocated when this allocator is 
destructed.
+
+        \param buffer User supplied buffer.
+        \param size Size of the buffer in bytes. It must at least larger than 
sizeof(ChunkHeader).
+        \param chunkSize The size of memory chunk. The default is 
kDefaultChunkSize.
+        \param baseAllocator The allocator for allocating memory chunks.
+    */
+    MemoryPoolAllocator(void *buffer, size_t size, size_t chunkSize = 
kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
+        chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(buffer), 
baseAllocator_(baseAllocator), ownBaseAllocator_(0)
+    {
+        RAPIDJSON_ASSERT(buffer != 0);
+        RAPIDJSON_ASSERT(size > sizeof(ChunkHeader));
+        chunkHead_ = reinterpret_cast<ChunkHeader*>(buffer);
+        chunkHead_->capacity = size - sizeof(ChunkHeader);
+        chunkHead_->size = 0;
+        chunkHead_->next = 0;
+    }
+
+    //! Destructor.
+    /*! This deallocates all memory chunks, excluding the user-supplied buffer.
+    */
+    ~MemoryPoolAllocator() {
+        Clear();
+        RAPIDJSON_DELETE(ownBaseAllocator_);
+    }
+
+    //! Deallocates all memory chunks, excluding the user-supplied buffer.
+    void Clear() {
+        while (chunkHead_ && chunkHead_ != userBuffer_) {
+            ChunkHeader* next = chunkHead_->next;
+            baseAllocator_->Free(chunkHead_);
+            chunkHead_ = next;
+        }
+        if (chunkHead_ && chunkHead_ == userBuffer_)
+            chunkHead_->size = 0; // Clear user buffer
+    }
+
+    //! Computes the total capacity of allocated memory chunks.
+    /*! \return total capacity in bytes.
+    */
+    size_t Capacity() const {
+        size_t capacity = 0;
+        for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)
+            capacity += c->capacity;
+        return capacity;
+    }
+
+    //! Computes the memory blocks allocated.
+    /*! \return total used bytes.
+    */
+    size_t Size() const {
+        size_t size = 0;
+        for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)
+            size += c->size;
+        return size;
+    }
+
+    //! Allocates a memory block. (concept Allocator)
+    void* Malloc(size_t size) {
+        if (!size)
+            return NULL;
+
+        size = RAPIDJSON_ALIGN(size);
+        if (chunkHead_ == 0 || chunkHead_->size + size > chunkHead_->capacity)
+            if (!AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size))
+                return NULL;
+
+        void *buffer = reinterpret_cast<char *>(chunkHead_) + 
RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size;
+        chunkHead_->size += size;
+        return buffer;
+    }
+
+    //! Resizes a memory block (concept Allocator)
+    void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
+        if (originalPtr == 0)
+            return Malloc(newSize);
+
+        if (newSize == 0)
+            return NULL;
+
+        originalSize = RAPIDJSON_ALIGN(originalSize);
+        newSize = RAPIDJSON_ALIGN(newSize);
+
+        // Do not shrink if new size is smaller than original
+        if (originalSize >= newSize)
+            return originalPtr;
+
+        // Simply expand it if it is the last allocation and there is 
sufficient space
+        if (originalPtr == reinterpret_cast<char *>(chunkHead_) + 
RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size - originalSize) {
+            size_t increment = static_cast<size_t>(newSize - originalSize);
+            if (chunkHead_->size + increment <= chunkHead_->capacity) {
+                chunkHead_->size += increment;
+                return originalPtr;
+            }
+        }
+
+        // Realloc process: allocate and copy memory, do not free original 
buffer.
+        if (void* newBuffer = Malloc(newSize)) {
+            if (originalSize)
+                std::memcpy(newBuffer, originalPtr, originalSize);
+            return newBuffer;
+        }
+        else
+            return NULL;
+    }
+
+    //! Frees a memory block (concept Allocator)
+    static void Free(void *ptr) { (void)ptr; } // Do nothing
+
+private:
+    //! Copy constructor is not permitted.
+    MemoryPoolAllocator(const MemoryPoolAllocator& rhs) /* = delete */;
+    //! Copy assignment operator is not permitted.
+    MemoryPoolAllocator& operator=(const MemoryPoolAllocator& rhs) /* = delete 
*/;
+
+    //! Creates a new chunk.
+    /*! \param capacity Capacity of the chunk in bytes.
+        \return true if success.
+    */
+    bool AddChunk(size_t capacity) {
+        if (!baseAllocator_)
+            ownBaseAllocator_ = baseAllocator_ = 
RAPIDJSON_NEW(BaseAllocator)();
+        if (ChunkHeader* chunk = 
reinterpret_cast<ChunkHeader*>(baseAllocator_->Malloc(RAPIDJSON_ALIGN(sizeof(ChunkHeader))
 + capacity))) {
+            chunk->capacity = capacity;
+            chunk->size = 0;
+            chunk->next = chunkHead_;
+            chunkHead_ =  chunk;
+            return true;
+        }
+        else
+            return false;
+    }
+
+    static const int kDefaultChunkCapacity = 64 * 1024; //!< Default chunk 
capacity.
+
+    //! Chunk header for perpending to each chunk.
+    /*! Chunks are stored as a singly linked list.
+    */
+    struct ChunkHeader {
+        size_t capacity;    //!< Capacity of the chunk in bytes (excluding the 
header itself).
+        size_t size;        //!< Current size of allocated memory in bytes.
+        ChunkHeader *next;  //!< Next chunk in the linked list.
+    };
+
+    ChunkHeader *chunkHead_;    //!< Head of the chunk linked-list. Only the 
head chunk serves allocation.
+    size_t chunk_capacity_;     //!< The minimum capacity of chunk when they 
are allocated.
+    void *userBuffer_;          //!< User supplied buffer.
+    BaseAllocator* baseAllocator_;  //!< base allocator for allocating memory 
chunks.
+    BaseAllocator* ownBaseAllocator_;   //!< base allocator created by this 
object.
+};
+
+RAPIDJSON_NAMESPACE_END
+
+#endif // RAPIDJSON_ENCODINGS_H_


Reply via email to