text:
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * vim: sw=2 ts=8 et :
 */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "base/basictypes.h"

#include "BasicLayers.h"
#include "gfx3DMatrix.h"
#include "LayerManagerOGL.h"
#ifdef MOZ_ENABLE_D3D9_LAYER
# include "LayerManagerD3D9.h"
#endif //MOZ_ENABLE_D3D9_LAYER
#include "mozilla/BrowserElementParent.h"
#include "mozilla/dom/TabParent.h"
#include "mozilla/layers/AsyncPanZoomController.h"
#include "mozilla/layers/CompositorParent.h"
#include "mozilla/layers/ShadowLayersParent.h"
#include "nsContentUtils.h"
#include "nsFrameLoader.h"
#include "nsIObserver.h"
#include "nsSubDocumentFrame.h"
#include "nsViewportFrame.h"
#include "RenderFrameParent.h"

typedef nsContentView::ViewConfig ViewConfig;
using namespace mozilla::dom;
using namespace mozilla::layers;

namespace mozilla {
namespace layout {

typedef FrameMetrics::ViewID ViewID;
typedef RenderFrameParent::ViewMap ViewMap;

// Represents (affine) transforms that are calculated from a content view.
struct ViewTransform {
  ViewTransform(nsIntPoint aTranslation = nsIntPoint(0, 0), float aXScale = 1, float aYScale = 1)
    : mTranslation(aTranslation)
    , mXScale(aXScale)
    , mYScale(aYScale)
  {}

  operator gfx3DMatrix() const
  {
    return
      gfx3DMatrix::ScalingMatrix(mXScale, mYScale, 1) *
      gfx3DMatrix::Translation(mTranslation.x, mTranslation.y, 0);
  }

  nsIntPoint mTranslation;
  float mXScale;
  float mYScale;
};

// Matrix helpers
// For our simple purposes, these helpers apply to 2D affine transformations
// that can be represented by a scale and a translation. This makes the math
// much easier because we only expect the diagonals and the translation
// coordinates of the matrix to be non-zero.

static double GetXScale(const gfx3DMatrix& aTransform)
{
  return aTransform._11;
}

static double GetYScale(const gfx3DMatrix& aTransform)
{
  return aTransform._22;
}

static void Scale(gfx3DMatrix& aTransform, double aXScale, double aYScale)
{
  aTransform._11 *= aXScale;
  aTransform._22 *= aYScale;
}

static void ReverseTranslate(gfx3DMatrix& aTransform, const gfxPoint& aOffset)
{
  aTransform._41 -= aOffset.x;
  aTransform._42 -= aOffset.y;
}

static void ApplyTransform(nsRect& aRect,
                           gfx3DMatrix& aTransform,
                           nscoord auPerDevPixel)
{
  aRect.x = aRect.x * aTransform._11 + aTransform._41 * auPerDevPixel;
  aRect.y = aRect.y * aTransform._22 + aTransform._42 * auPerDevPixel;
  aRect.width = aRect.width * aTransform._11;
  aRect.height = aRect.height * aTransform._22;
}

static void
AssertInTopLevelChromeDoc(ContainerLayer* aContainer,
                          nsIFrame* aContainedFrame)
{
  NS_ASSERTION(
    (aContainer->Manager()->GetBackendType() != mozilla::layers::LAYERS_BASIC) ||
    (aContainedFrame->GetNearestWidget() ==
     static_cast<BasicLayerManager*>(aContainer->Manager())->GetRetainerWidget()),
    "Expected frame to be in top-level chrome document");
}

// Return view for given ID in aArray, NULL if not found.
static nsContentView*
FindViewForId(const ViewMap& aMap, ViewID aId)
{
  ViewMap::const_iterator iter = aMap.find(aId);
  return iter != aMap.end() ? iter->second : NULL;
}

static const FrameMetrics*
GetFrameMetrics(Layer* aLayer)
{
  ContainerLayer* container = aLayer->AsContainerLayer();
  return container ? &container->GetFrameMetrics() : NULL;
}

/**
 * Gets the layer-pixel offset of aContainerFrame's content rect top-left
 * from the nearest display item reference frame (which we assume will be inducing
 * a ContainerLayer).
 */
static nsIntPoint
GetContentRectLayerOffset(nsIFrame* aContainerFrame, nsDisplayListBuilder* aBuilder)
{
  nscoord auPerDevPixel = aContainerFrame->PresContext()->AppUnitsPerDevPixel();

  // Offset to the content rect in case we have borders or padding
  // Note that aContainerFrame could be a reference frame itself, so
  // we need to be careful here to ensure that we call ToReferenceFrame
  // on aContainerFrame and not its parent.
  nsPoint frameOffset = aBuilder->ToReferenceFrame(aContainerFrame) +
    (aContainerFrame->GetContentRect().TopLeft() - aContainerFrame->GetPosition());

  return frameOffset.ToNearestPixels(auPerDevPixel);
}

// Compute the transform of the shadow tree contained by
// |aContainerFrame| to widget space.  We transform because the
// subprocess layer manager renders to a different top-left than where
// the shadow tree is drawn here and because a scale can be set on the
// shadow tree.
static ViewTransform
ComputeShadowTreeTransform(nsIFrame* aContainerFrame,
                           nsFrameLoader* aRootFrameLoader,
                           const FrameMetrics* aMetrics,
                           const ViewConfig& aConfig,
                           float aTempScaleX = 1.0,
                           float aTempScaleY = 1.0)
{
  // |aMetrics->mViewportScrollOffset| The frame's scroll offset when it was
  //                                   painted, in content document pixels.
  // |aConfig.mScrollOffset|           What our user expects, or wants, the
  //                                   frame scroll offset to be in chrome
  //                                   document app units.
  //
  // So we set a compensating translation that moves the content document
  // pixels to where the user wants them to be.
  //
  nscoord auPerDevPixel = aContainerFrame->PresContext()->AppUnitsPerDevPixel();
  nsIntPoint scrollOffset =
    aConfig.mScrollOffset.ToNearestPixels(auPerDevPixel);
  // metricsScrollOffset is in layer coordinates.
  gfxPoint metricsScrollOffset = aMetrics->GetScrollOffsetInLayerPixels();
  nsIntPoint roundedMetricsScrollOffset =
    nsIntPoint(NS_lround(metricsScrollOffset.x), NS_lround(metricsScrollOffset.y));

  if (aRootFrameLoader->AsyncScrollEnabled() && !aMetrics->mDisplayPort.IsEmpty()) {
    // Only use asynchronous scrolling if it is enabled and there is a
    // displayport defined. It is useful to have a scroll layer that is
    // synchronously scrolled for identifying a scroll area before it is
    // being actively scrolled.
    nsIntPoint scrollCompensation(
      (scrollOffset.x / aTempScaleX - roundedMetricsScrollOffset.x) * aConfig.mXScale,
      (scrollOffset.y / aTempScaleY - roundedMetricsScrollOffset.y) * aConfig.mYScale);

    return ViewTransform(-scrollCompensation, aConfig.mXScale, aConfig.mYScale);
  } else {
    return ViewTransform(nsIntPoint(0, 0), 1, 1);
  }
}

// Use shadow layer tree to build display list for the browser's frame.
static void
BuildListForLayer(Layer* aLayer,
                  nsFrameLoader* aRootFrameLoader,
                  const gfx3DMatrix& aTransform,
                  nsDisplayListBuilder* aBuilder,
                  nsDisplayList& aShadowTree,
                  nsIFrame* aSubdocFrame)
{
  const FrameMetrics* metrics = GetFrameMetrics(aLayer);

  gfx3DMatrix transform;

  if (metrics && metrics->IsScrollable()) {
    const ViewID scrollId = metrics->mScrollId;

    // We need to figure out the bounds of the scrollable region using the
    // shadow layer tree from the remote process. The metrics viewport is
    // defined based on all the transformations of its parent layers and
    // the scale of the current layer.

    // Calculate transform for this layer.
    nsContentView* view =
      aRootFrameLoader->GetCurrentRemoteFrame()->GetContentView(scrollId);
    // XXX why don't we include aLayer->GetTransform() in the inverse-scale here?
    // This seems wrong, but it doesn't seem to cause bugs!
    gfx3DMatrix applyTransform = ComputeShadowTreeTransform(
      aSubdocFrame, aRootFrameLoader, metrics, view->GetViewConfig(),
      1 / GetXScale(aTransform), 1 / GetYScale(aTransform));
    transform = applyTransform * aLayer->GetTransform() * aTransform;

    // As mentioned above, bounds calculation also depends on the scale
    // of this layer.
    gfx3DMatrix tmpTransform = aTransform;
    Scale(tmpTransform, GetXScale(applyTransform), GetYScale(applyTransform));

    // Calculate rect for this layer based on aTransform.
    nsRect bounds;
    {
      nscoord auPerCSSPixel = nsPresContext::AppUnitsPerCSSPixel();
      nscoord auPerDevPixel = aSubdocFrame->PresContext()->AppUnitsPerDevPixel();
      gfx::Rect viewport = metrics->mViewport;
      bounds = nsIntRect(viewport.x, viewport.y,
                         viewport.width, viewport.height).ToAppUnits(auPerCSSPixel);
      ApplyTransform(bounds, tmpTransform, auPerDevPixel);

    }

    aShadowTree.AppendToTop(
      new (aBuilder) nsDisplayRemoteShadow(aBuilder, aSubdocFrame, bounds, scrollId));

  } else {
    transform = aLayer->GetTransform() * aTransform;
  }

  for (Layer* child = aLayer->GetFirstChild(); child;
       child = child->GetNextSibling()) {
    BuildListForLayer(child, aRootFrameLoader, transform,
                      aBuilder, aShadowTree, aSubdocFrame);
  }
}

// Go down shadow layer tree and apply transformations for scrollable layers.
static void
TransformShadowTree(nsDisplayListBuilder* aBuilder, nsFrameLoader* aFrameLoader,
                    nsIFrame* aFrame, Layer* aLayer,
                    const ViewTransform& aTransform,
                    float aTempScaleDiffX = 1.0,
                    float aTempScaleDiffY = 1.0)
{
  ShadowLayer* shadow = aLayer->AsShadowLayer();
  shadow->SetShadowClipRect(aLayer->GetClipRect());
  shadow->SetShadowVisibleRegion(aLayer->GetVisibleRegion());
  shadow->SetShadowOpacity(aLayer->GetOpacity());

  const FrameMetrics* metrics = GetFrameMetrics(aLayer);

  gfx3DMatrix shadowTransform = aLayer->GetTransform();
  ViewTransform layerTransform = aTransform;

  if (metrics && metrics->IsScrollable()) {
    const ViewID scrollId = metrics->mScrollId;
    const nsContentView* view =
      aFrameLoader->GetCurrentRemoteFrame()->GetContentView(scrollId);
    NS_ABORT_IF_FALSE(view, "Array of views should be consistent with layer tree");
    const gfx3DMatrix& currentTransform = aLayer->GetTransform();

    const ViewConfig& config = view->GetViewConfig();
    // With temporary scale we should compensate translation
    // using temporary scale value
    aTempScaleDiffX *= GetXScale(shadowTransform) * config.mXScale;
    aTempScaleDiffY *= GetYScale(shadowTransform) * config.mYScale;
    ViewTransform viewTransform = ComputeShadowTreeTransform(
      aFrame, aFrameLoader, metrics, view->GetViewConfig(),
      aTempScaleDiffX, aTempScaleDiffY
    );

    // Apply the layer's own transform *before* the view transform
    shadowTransform = gfx3DMatrix(viewTransform) * currentTransform;

    layerTransform = viewTransform;
    if (metrics->IsRootScrollable()) {
      // Apply the translation *before* we do the rest of the transforms.
      nsIntPoint offset = GetContentRectLayerOffset(aFrame, aBuilder);
      shadowTransform = shadowTransform *
          gfx3DMatrix::Translation(float(offset.x), float(offset.y), 0.0);
    }
  }

  if (aLayer->GetIsFixedPosition() &&
      !aLayer->GetParent()->GetIsFixedPosition()) {
    // Alter the shadow transform of fixed position layers in the situation
    // that the view transform's scroll position doesn't match the actual
    // scroll position, due to asynchronous layer scrolling.
    float offsetX = layerTransform.mTranslation.x / layerTransform.mXScale;
    float offsetY = layerTransform.mTranslation.y / layerTransform.mYScale;
    ReverseTranslate(shadowTransform, gfxPoint(offsetX, offsetY));
    const nsIntRect* clipRect = shadow->GetShadowClipRect();
    if (clipRect) {
      nsIntRect transformedClipRect(*clipRect);
      transformedClipRect.MoveBy(-offsetX, -offsetY);
      shadow->SetShadowClipRect(&transformedClipRect);
    }
  }

  // The transform already takes the resolution scale into account.  Since we
  // will apply the resolution scale again when computing the effective
  // transform, we must apply the inverse resolution scale here.
  if (ContainerLayer* c = aLayer->AsContainerLayer()) {
    shadowTransform.Scale(1.0f/c->GetPreXScale(),
                          1.0f/c->GetPreYScale(),
                          1);
  }
  shadowTransform.ScalePost(1.0f/aLayer->GetPostXScale(),
                            1.0f/aLayer->GetPostYScale(),
                            1);

  shadow->SetShadowTransform(shadowTransform);
  for (Layer* child = aLayer->GetFirstChild();
       child; child = child->GetNextSibling()) {
    TransformShadowTree(aBuilder, aFrameLoader, aFrame, child, layerTransform,
                        aTempScaleDiffX, aTempScaleDiffY);
  }
}

static void
ClearContainer(ContainerLayer* aContainer)
{
  while (Layer* layer = aContainer->GetFirstChild()) {
    aContainer->RemoveChild(layer);
  }
}

// Return true iff |aManager| is a "temporary layer manager".  They're
// used for small software rendering tasks, like drawWindow.  That's
// currently implemented by a BasicLayerManager without a backing
// widget, and hence in non-retained mode.
inline static bool
IsTempLayerManager(LayerManager* aManager)
{
  return (mozilla::layers::LAYERS_BASIC == aManager->GetBackendType() &&
          !static_cast<BasicLayerManager*>(aManager)->IsRetained());
}

// Recursively create a new array of scrollables, preserving any scrollables
// that are still in the layer tree.
//
// aXScale and aYScale are used to calculate any values that need to be in
// chrome-document CSS pixels and aren't part of the rendering loop, such as
// the initial scroll offset for a new view.
static void
BuildViewMap(ViewMap& oldContentViews, ViewMap& newContentViews,
             nsFrameLoader* aFrameLoader, Layer* aLayer,
             float aXScale = 1, float aYScale = 1,
             float aAccConfigXScale = 1, float aAccConfigYScale = 1)
{
  ContainerLayer* container = aLayer->AsContainerLayer();
  if (!container)
    return;
  const FrameMetrics metrics = container->GetFrameMetrics();
  const ViewID scrollId = metrics.mScrollId;
  const gfx3DMatrix transform = aLayer->GetTransform();
  aXScale *= GetXScale(transform);
  aYScale *= GetYScale(transform);

  if (metrics.IsScrollable()) {
    nscoord auPerDevPixel = aFrameLoader->GetPrimaryFrameOfOwningContent()
                                        ->PresContext()->AppUnitsPerDevPixel();
    nscoord auPerCSSPixel = auPerDevPixel * metrics.mDevPixelsPerCSSPixel;
    nsContentView* view = FindViewForId(oldContentViews, scrollId);
    if (view) {
      // View already exists. Be sure to propagate scales for any values
      // that need to be calculated something in chrome-doc CSS pixels.
      ViewConfig config = view->GetViewConfig();
      aXScale *= config.mXScale;
      aYScale *= config.mYScale;
      view->mFrameLoader = aFrameLoader;
      // If scale has changed, then we should update
      // current scroll offset to new scaled value
      if (aAccConfigXScale != view->mParentScaleX ||
          aAccConfigYScale != view->mParentScaleY) {
        float xscroll = 0, yscroll = 0;
        view->GetScrollX(&xscroll);
        view->GetScrollY(&yscroll);
        xscroll = xscroll * (aAccConfigXScale / view->mParentScaleX);
        yscroll = yscroll * (aAccConfigYScale / view->mParentScaleY);
        view->ScrollTo(xscroll, yscroll);
        view->mParentScaleX = aAccConfigXScale;
        view->mParentScaleY = aAccConfigYScale;
      }
      // Collect only config scale values for scroll compensation
      aAccConfigXScale *= config.mXScale;
      aAccConfigYScale *= config.mYScale;
    } else {
      // View doesn't exist, so generate one. We start the view scroll offset at
      // the same position as the framemetric's scroll offset from the layer.
      // The default scale is 1, so no need to propagate scale down.
      ViewConfig config;
      config.mScrollOffset = nsPoint(
        NSIntPixelsToAppUnits(metrics.mScrollOffset.x, auPerCSSPixel) * aXScale,
        NSIntPixelsToAppUnits(metrics.mScrollOffset.y, auPerCSSPixel) * aYScale);
      view = new nsContentView(aFrameLoader, scrollId, config);
      view->mParentScaleX = aAccConfigXScale;
      view->mParentScaleY = aAccConfigYScale;
    }

    view->mViewportSize = nsSize(
      NSIntPixelsToAppUnits(metrics.mViewport.width, auPerDevPixel) * aXScale,
      NSIntPixelsToAppUnits(metrics.mViewport.height, auPerDevPixel) * aYScale);
    view->mContentSize = nsSize(
      NSIntPixelsToAppUnits(metrics.mContentRect.width, auPerDevPixel) * aXScale,
      NSIntPixelsToAppUnits(metrics.mContentRect.height, auPerDevPixel) * aYScale);

    newContentViews[scrollId] = view;
  }

  for (Layer* child = aLayer->GetFirstChild();
       child; child = child->GetNextSibling()) {
    BuildViewMap(oldContentViews, newContentViews, aFrameLoader, child,
                 aXScale, aYScale, aAccConfigXScale, aAccConfigYScale);
  }
}

static void
BuildBackgroundPatternFor(ContainerLayer* aContainer,
                          ContainerLayer* aShadowRoot,
                          const ViewConfig& aConfig,
                          const gfxRGBA& aColor,
                          LayerManager* aManager,
                          nsIFrame* aFrame)
{
  ShadowLayer* shadowRoot = aShadowRoot->AsShadowLayer();
  gfxMatrix t;
  if (!shadowRoot->GetShadowTransform().Is2D(&t)) {
    return;
  }

  // Get the rect bounding the shadow content, transformed into the
  // same space as |aFrame|
  nsIntRect contentBounds = shadowRoot->GetShadowVisibleRegion().GetBounds();
  gfxRect contentVis(contentBounds.x, contentBounds.y,
                     contentBounds.width, contentBounds.height);
  gfxRect localContentVis(t.Transform(contentVis));
  // Round *in* here because this area is punched out of the background
  localContentVis.RoundIn();
  nsIntRect localIntContentVis(localContentVis.X(), localContentVis.Y(),
                               localContentVis.Width(), localContentVis.Height());

  // Get the frame's rect
  nscoord auPerDevPixel = aFrame->PresContext()->AppUnitsPerDevPixel();
  nsIntRect frameRect = aFrame->GetRect().ToOutsidePixels(auPerDevPixel);

  // If the shadow tree covers the frame rect, don't bother building
  // the background, it wouldn't be visible
  if (localIntContentVis.Contains(frameRect)) {
    return;
  }
  nsRefPtr<ColorLayer> layer = aManager->CreateColorLayer();
  layer->SetColor(aColor);

  // The visible area of the background is the frame's area minus the
  // content area
  nsIntRegion bgRgn(frameRect);
  bgRgn.Sub(bgRgn, localIntContentVis);
  bgRgn.MoveBy(-frameRect.TopLeft());
  layer->SetVisibleRegion(bgRgn);

  aContainer->InsertAfter(layer, nullptr);
}

already_AddRefed<LayerManager>
GetFrom(nsFrameLoader* aFrameLoader)
{
  nsIDocument* doc = aFrameLoader->GetOwnerDoc();
  return nsContentUtils::LayerManagerForDocument(doc);
}

class RemoteContentController : public GeckoContentController {
public:
  RemoteContentController(RenderFrameParent* aRenderFrame)
    : mUILoop(MessageLoop::current())
    , mRenderFrame(aRenderFrame)
  { }

  virtual void RequestContentRepaint(const FrameMetrics& aFrameMetrics) MOZ_OVERRIDE
  {
    // We always need to post requests into the "UI thread" otherwise the
    // requests may get processed out of order.
    mUILoop->PostTask(
      FROM_HERE,
      NewRunnableMethod(this, &RemoteContentController::DoRequestContentRepaint,
                        aFrameMetrics));
  }

  virtual void HandleDoubleTap(const nsIntPoint& aPoint) MOZ_OVERRIDE
  {
    if (MessageLoop::current() != mUILoop) {
      // We have to send this message from the "UI thread" (main
      // thread).
      mUILoop->PostTask(
        FROM_HERE,
        NewRunnableMethod(this, &RemoteContentController::HandleDoubleTap,
                          aPoint));
      return;
    }
    if (mRenderFrame) {
      TabParent* browser = static_cast<TabParent*>(mRenderFrame->Manager());
      browser->HandleDoubleTap(aPoint);
    }
  }

  virtual void HandleSingleTap(const nsIntPoint& aPoint) MOZ_OVERRIDE
  {
    if (MessageLoop::current() != mUILoop) {
      // We have to send this message from the "UI thread" (main
      // thread).
      mUILoop->PostTask(
        FROM_HERE,
        NewRunnableMethod(this, &RemoteContentController::HandleSingleTap,
                          aPoint));
      return;
    }
    if (mRenderFrame) {
      TabParent* browser = static_cast<TabParent*>(mRenderFrame->Manager());
      browser->HandleSingleTap(aPoint);
    }
  }

  virtual void HandleLongTap(const nsIntPoint& aPoint) MOZ_OVERRIDE
  {
    if (MessageLoop::current() != mUILoop) {
      // We have to send this message from the "UI thread" (main
      // thread).
      mUILoop->PostTask(
        FROM_HERE,
        NewRunnableMethod(this, &RemoteContentController::HandleLongTap,
                          aPoint));
      return;
    }
    if (mRenderFrame) {
      TabParent* browser = static_cast<TabParent*>(mRenderFrame->Manager());
      browser->HandleLongTap(aPoint);
    }
  }

  void ClearRenderFrame() { mRenderFrame = nullptr; }

  virtual void SendAsyncScrollDOMEvent(const gfx::Rect& aContentRect,
                                       const gfx::Size& aContentSize) MOZ_OVERRIDE
  {
    if (MessageLoop::current() != mUILoop) {
      mUILoop->PostTask(
        FROM_HERE,
        NewRunnableMethod(this,
                          &RemoteContentController::SendAsyncScrollDOMEvent,
                          aContentRect, aContentSize));
      return;
    }
    if (mRenderFrame) {
      TabParent* browser = static_cast<TabParent*>(mRenderFrame->Manager());
      BrowserElementParent::DispatchAsyncScrollEvent(browser, aContentRect,
                                                     aContentSize);
    }
  }

private:
  void DoRequestContentRepaint(const FrameMetrics& aFrameMetrics)
  {
    if (mRenderFrame) {
      TabParent* browser = static_cast<TabParent*>(mRenderFrame->Manager());
      browser->UpdateFrame(aFrameMetrics);
    }
  }

  MessageLoop* mUILoop;
  RenderFrameParent* mRenderFrame;
};

RenderFrameParent::RenderFrameParent(nsFrameLoader* aFrameLoader,
                                     ScrollingBehavior aScrollingBehavior,
                                     LayersBackend* aBackendType,
                                     int* aMaxTextureSize,
                                     uint64_t* aId)
  : mLayersId(0)
  , mFrameLoader(aFrameLoader)
  , mFrameLoaderDestroyed(false)
  , mBackgroundColor(gfxRGBA(1, 1, 1))
{
  mContentViews[FrameMetrics::ROOT_SCROLL_ID] =
    new nsContentView(aFrameLoader, FrameMetrics::ROOT_SCROLL_ID);

  *aBackendType = mozilla::layers::LAYERS_NONE;
  *aMaxTextureSize = 0;
  *aId = 0;

  nsRefPtr<LayerManager> lm = GetFrom(mFrameLoader);
  // Perhaps the document containing this frame currently has no presentation?
  if (lm) {
    *aBackendType = lm->GetBackendType();
    *aMaxTextureSize = lm->GetMaxTextureSize();
  }

  if (CompositorParent::CompositorLoop()) {
    // Our remote frame will push layers updates to the compositor,
    // and we'll keep an indirect reference to that tree.
    *aId = mLayersId = CompositorParent::AllocateLayerTreeId();
    if (aScrollingBehavior == ASYNC_PAN_ZOOM) {
      mContentController = new RemoteContentController(this);
      mPanZoomController = new AsyncPanZoomController(
        mContentController, AsyncPanZoomController::USE_GESTURE_DETECTOR);
      CompositorParent::SetPanZoomControllerForLayerTree(mLayersId,
                                                         mPanZoomController);
    }
  }
}

RenderFrameParent::~RenderFrameParent()
{}

void
RenderFrameParent::Destroy()
{
  size_t numChildren = ManagedPLayersParent().Length();
  NS_ABORT_IF_FALSE(0 == numChildren || 1 == numChildren,
                    "render frame must only have 0 or 1 layer manager");

  if (numChildren) {
    ShadowLayersParent* layers =
      static_cast<ShadowLayersParent*>(ManagedPLayersParent()[0]);
    layers->Destroy();
  }

  mFrameLoaderDestroyed = true;
}

nsContentView*
RenderFrameParent::GetContentView(ViewID aId)
{
  return FindViewForId(mContentViews, aId);
}

void
RenderFrameParent::ContentViewScaleChanged(nsContentView* aView)
{
  // Since the scale has changed for a view, it and its descendents need their
  // shadow-space attributes updated. It's easiest to rebuild the view map.
  BuildViewMap();
}

void
RenderFrameParent::ShadowLayersUpdated(ShadowLayersParent* aLayerTree,
                                       const TargetConfig& aTargetConfig,
                                       bool isFirstPaint)
{
  // View map must only contain views that are associated with the current
  // shadow layer tree. We must always update the map when shadow layers
  // are updated.
  BuildViewMap();

  TriggerRepaint();
}

already_AddRefed<Layer>
RenderFrameParent::BuildLayer(nsDisplayListBuilder* aBuilder,
                              nsIFrame* aFrame,
                              LayerManager* aManager,
                              const nsIntRect& aVisibleRect,
                              nsDisplayItem* aItem,
                              const ContainerParameters& aContainerParameters)
{
  NS_ABORT_IF_FALSE(aFrame,
                    "makes no sense to have a shadow tree without a frame");
  NS_ABORT_IF_FALSE(!mContainer ||
                    IsTempLayerManager(aManager) ||
                    mContainer->Manager() == aManager,
                    "retaining manager changed out from under us ... HELP!");

  if (IsTempLayerManager(aManager) ||
      (mContainer && mContainer->Manager() != aManager)) {
    // This can happen if aManager is a "temporary" manager, or if the
    // widget's layer manager changed out from under us.  We need to
    // FIXME handle the former case somehow, probably with an API to
    // draw a manager's subtree.  The latter is bad bad bad, but the
    // the NS_ABORT_IF_FALSE() above will flag it.  Returning NULL
    // here will just cause the shadow subtree not to be rendered.
    NS_WARNING("Remote iframe not rendered");
    return nullptr;
  }

  uint64_t id = GetLayerTreeId();
  if (0 != id) {
    MOZ_ASSERT(!GetRootLayer());

    nsRefPtr<Layer> layer =
      (aManager->GetLayerBuilder()->GetLeafLayerFor(aBuilder, aItem));
    if (!layer) {
      layer = aManager->CreateRefLayer();
    }
    if (!layer) {
      // Probably a temporary layer manager that doesn't know how to
      // use ref layers.
      return nullptr;
    }
    static_cast<RefLayer*>(layer.get())->SetReferentId(id);
    layer->SetVisibleRegion(aVisibleRect);
    nsIntPoint offset = GetContentRectLayerOffset(aFrame, aBuilder);
    // We can only have an offset if we're a child of an inactive
    // container, but our display item is LAYER_ACTIVE_FORCE which
    // forces all layers above to be active.
    MOZ_ASSERT(aContainerParameters.mOffset == nsIntPoint());
    gfx3DMatrix m =
      gfx3DMatrix::Translation(offset.x, offset.y, 0.0);
    // Remote content can't be repainted by us, so we multiply down
    // the resolution that our container expects onto our container.
    m.Scale(aContainerParameters.mXScale, aContainerParameters.mYScale, 1.0);
    layer->SetBaseTransform(m);

    return layer.forget();
  }

  if (mContainer) {
    ClearContainer(mContainer);
    mContainer->SetPreScale(1.0f, 1.0f);
    mContainer->SetPostScale(1.0f, 1.0f);
    mContainer->SetInheritedScale(1.0f, 1.0f);
  }

  ContainerLayer* shadowRoot = GetRootLayer();
  if (!shadowRoot) {
    mContainer = nullptr;
    return nullptr;
  }

  NS_ABORT_IF_FALSE(!shadowRoot || shadowRoot->Manager() == aManager,
                    "retaining manager changed out from under us ... HELP!");

  // Wrap the shadow layer tree in mContainer.
  if (!mContainer) {
    mContainer = aManager->CreateContainerLayer();
  }
  NS_ABORT_IF_FALSE(!mContainer->GetFirstChild(),
                    "container of shadow tree shouldn't have a 'root' here");

  mContainer->InsertAfter(shadowRoot, nullptr);

  AssertInTopLevelChromeDoc(mContainer, aFrame);
  ViewTransform transform;
  TransformShadowTree(aBuilder, mFrameLoader, aFrame, shadowRoot, transform);
  mContainer->SetClipRect(nullptr);

  if (mFrameLoader->AsyncScrollEnabled()) {
    const nsContentView* view = GetContentView(FrameMetrics::ROOT_SCROLL_ID);
    BuildBackgroundPatternFor(mContainer,
                              shadowRoot,
                              view->GetViewConfig(),
                              mBackgroundColor,
                              aManager, aFrame);
  }
  mContainer->SetVisibleRegion(aVisibleRect);

  return nsRefPtr<Layer>(mContainer).forget();
}

void
RenderFrameParent::OwnerContentChanged(nsIContent* aContent)
{
  NS_ABORT_IF_FALSE(mFrameLoader->GetOwnerContent() == aContent,
                    "Don't build new map if owner is same!");
  BuildViewMap();
}

void
RenderFrameParent::NotifyInputEvent(const nsInputEvent& aEvent,
                                    nsInputEvent* aOutEvent)
{
  if (mPanZoomController) {
    mPanZoomController->ReceiveInputEvent(aEvent, aOutEvent);
  }
}

void
RenderFrameParent::NotifyDimensionsChanged(int width, int height)
{
  if (mPanZoomController) {
    mPanZoomController->UpdateCompositionBounds(
      nsIntRect(0, 0, width, height));
  }
}

void
RenderFrameParent::ActorDestroy(ActorDestroyReason why)
{
  if (mLayersId != 0) {
    CompositorParent::DeallocateLayerTreeId(mLayersId);
    if (mContentController) {
      // Stop our content controller from requesting repaints of our
      // content.
      mContentController->ClearRenderFrame();
      mPanZoomController->Destroy();
    }
  }

  if (mFrameLoader && mFrameLoader->GetCurrentRemoteFrame() == this) {
    // XXX this might cause some weird issues ... we'll just not
    // redraw the part of the window covered by this until the "next"
    // remote frame has a layer-tree transaction.  For
    // why==NormalShutdown, we'll definitely want to do something
    // better, especially as nothing guarantees another Update() from
    // the "next" remote layer tree.
    mFrameLoader->SetCurrentRemoteFrame(nullptr);
  }
  mFrameLoader = nullptr;
}

bool
RenderFrameParent::RecvNotifyCompositorTransaction()
{
  TriggerRepaint();
  return true;
}

bool
RenderFrameParent::RecvCancelDefaultPanZoom()
{
  if (mPanZoomController) {
    mPanZoomController->CancelDefaultPanZoom();
  }
  return true;
}

bool
RenderFrameParent::RecvDetectScrollableSubframe()
{
  if (mPanZoomController) {
    mPanZoomController->DetectScrollableSubframe();
  }
  return true;
}

PLayersParent*
RenderFrameParent::AllocPLayers()
{
  if (!mFrameLoader || mFrameLoaderDestroyed) {
    return nullptr;
  }
  nsRefPtr<LayerManager> lm = GetFrom(mFrameLoader);
  return new ShadowLayersParent(lm->AsShadowManager(), this, 0);
}

bool
RenderFrameParent::DeallocPLayers(PLayersParent* aLayers)
{
  delete aLayers;
  return true;
}

void
RenderFrameParent::BuildViewMap()
{
  ViewMap newContentViews;
  // BuildViewMap assumes we have a primary frame, which may not be the case.
  if (GetRootLayer() && mFrameLoader->GetPrimaryFrameOfOwningContent()) {
    // Some of the content views in our hash map may no longer be active. To
    // tag them as inactive and to remove any chance of them using a dangling
    // pointer, we set mContentView to NULL.
    //
    // BuildViewMap will restore mFrameLoader if the content view is still
    // in our hash table.

    for (ViewMap::const_iterator iter = mContentViews.begin();
         iter != mContentViews.end();
         ++iter) {
      iter->second->mFrameLoader = NULL;
    }

    mozilla::layout::BuildViewMap(mContentViews, newContentViews, mFrameLoader, GetRootLayer());
  }

  // Here, we guarantee that *only* the root view is preserved in
  // case we couldn't build a new view map above. This is important because
  // the content view map should only contain the root view and content
  // views that are present in the layer tree.
  if (newContentViews.empty()) {
    newContentViews[FrameMetrics::ROOT_SCROLL_ID] =
      FindViewForId(mContentViews, FrameMetrics::ROOT_SCROLL_ID);
  }

  mContentViews = newContentViews;
}

void
RenderFrameParent::TriggerRepaint()
{
  mFrameLoader->SetCurrentRemoteFrame(this);

  nsIFrame* docFrame = mFrameLoader->GetPrimaryFrameOfOwningContent();
  if (!docFrame) {
    // Bad, but nothing we can do about it (XXX/cjones: or is there?
    // maybe bug 589337?).  When the new frame is created, we'll
    // probably still be the current render frame and will get to draw
    // our content then.  Or, we're shutting down and this update goes
    // to /dev/null.
    return;
  }

  docFrame->SchedulePaint();
}

ShadowLayersParent*
RenderFrameParent::GetShadowLayers() const
{
  const nsTArray<PLayersParent*>& shadowParents = ManagedPLayersParent();
  NS_ABORT_IF_FALSE(shadowParents.Length() <= 1,
                    "can only support at most 1 ShadowLayersParent");
  return (shadowParents.Length() == 1) ?
    static_cast<ShadowLayersParent*>(shadowParents[0]) : nullptr;
}

uint64_t
RenderFrameParent::GetLayerTreeId() const
{
  return mLayersId;
}

ContainerLayer*
RenderFrameParent::GetRootLayer() const
{
  ShadowLayersParent* shadowLayers = GetShadowLayers();
  return shadowLayers ? shadowLayers->GetRoot() : nullptr;
}

NS_IMETHODIMP
RenderFrameParent::BuildDisplayList(nsDisplayListBuilder* aBuilder,
                                    nsSubDocumentFrame* aFrame,
                                    const nsRect& aDirtyRect,
                                    const nsDisplayListSet& aLists)
{
  // We're the subdoc for <browser remote="true"> and it has
  // painted content.  Display its shadow layer tree.
  nsDisplayList shadowTree;
  ContainerLayer* container = GetRootLayer();
  if (aBuilder->IsForEventDelivery() && container) {
    ViewTransform offset =
      ViewTransform(GetContentRectLayerOffset(aFrame, aBuilder), 1, 1);
    BuildListForLayer(container, mFrameLoader, offset,
                      aBuilder, shadowTree, aFrame);
  } else {
    shadowTree.AppendToTop(
      new (aBuilder) nsDisplayRemote(aBuilder, aFrame, this));
  }

  // Clip the shadow layers to subdoc bounds
  nsPoint offset = aBuilder->ToReferenceFrame(aFrame);
  nsRect bounds = aFrame->EnsureInnerView()->GetBounds() + offset;

  return aLists.Content()->AppendNewToTop(
    new (aBuilder) nsDisplayClip(aBuilder, aFrame, &shadowTree,
                                 bounds));
}

void
RenderFrameParent::ZoomToRect(const gfxRect& aRect)
{
  if (mPanZoomController) {
    mPanZoomController->ZoomToRect(aRect);
  }
}

void
RenderFrameParent::ContentReceivedTouch(bool aPreventDefault)
{
  if (mPanZoomController) {
    mPanZoomController->ContentReceivedTouch(aPreventDefault);
  }
}

void
RenderFrameParent::UpdateZoomConstraints(bool aAllowZoom, float aMinZoom, float aMaxZoom)
{
  if (mPanZoomController) {
    mPanZoomController->UpdateZoomConstraints(aAllowZoom, aMinZoom, aMaxZoom);
  }
}

}  // namespace layout
}  // namespace mozilla

already_AddRefed<Layer>
nsDisplayRemote::BuildLayer(nsDisplayListBuilder* aBuilder,
                            LayerManager* aManager,
                            const ContainerParameters& aContainerParameters)
{
  int32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
  nsIntRect visibleRect = GetVisibleRect().ToNearestPixels(appUnitsPerDevPixel);
  visibleRect += aContainerParameters.mOffset;
  nsRefPtr<Layer> layer = mRemoteFrame->BuildLayer(aBuilder, mFrame, aManager, visibleRect, this, aContainerParameters);
  return layer.forget();
}

void
nsDisplayRemoteShadow::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
                         HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames)
{
  // If we are here, then rects have intersected.
  //
  // XXX I think iframes and divs can be rounded like anything else but we don't
  //     cover that case here.
  //
  if (aState->mShadows) {
    aState->mShadows->AppendElement(mId);
  }
}


16000+ Investors as on April 2019. Find Investors from 155 countries, 950+ industries. Finance your Business by sending your business proposal to pre-screened Investors with verified contact details and background information and investment requirements. Join our 739,000+ Member Network Today to Finance your Business.


text:
St David's Church, Naas is a Church of Ireland church in Naas, Ireland.

Location

St David's Church is located in the centre of Naas, on the east side of North Main Street,  southeast of the Moat of Naas. It is not to be confused with Naas's Roman Catholic church, which is called the Church of Our Lady and Saint David.

History

St David's Church was built on the site of an earlier Celtic Christian church dedicated to Saint Corban or St Patrick. Following the Norman conquest of Ireland (1169–75), William Fitzmaurice and the Cambro-Norman barons who settled in the Naas area rebuilt the church and dedicated it Saint David, patron saint of Wales. Up until about 1800 it was the custom in Naas to wear a leek on 1 March in honour of the saint.

In 1212 St David's was listed as one of the possessions of the Knights Hospitaller. By 1606, when St David's featured in the inquisition of James I, contained three chantries – Holy Trinity, St Mary, and St Catherine. The priests were appointed by the burgesses and provost of the town. William Pilsworth was named vicar in 1604. In 1620 the current building was constructed, incorporating much of the old Norman church. By 1767 the steeple was in a ruinous state and was pulled down. Joseph Bourke, 3rd Earl of Mayo decided to replace it but never completed the new tower; a plaque on the inside wall of the tower states "I found a ruin and left a steeple, Mayo 1783″.

The bell dates from 1674 and originally hung in the old steeple. The baptismal font is believed to be very old, predating the Norman church.

The church was excavated by T. Fanning in 1987–91, with many medieval tiles found.

Early Christians in Naas and the date of the present building

The stone structure of the church can be dated to around 1212 when we find the first recorded reference to St David's church listed  as a possession of the Hospitallers of St John of Jerusalem.

However, there was a Christian witness in Naas long before the existing building.  St Patrick is said to have visited the present site in the 5th century, where an early wooden church was constructed soon afterwards. The church at that time was probably dedicated to St Patrick or St Corban.  In 1175, Naas was occupied by Anglo Normans of Welsh extraction who constructed the present building.  St David is the patron saint of Wales and they felt that it was fitting to re-dedicate the newly constructed church to their national saint.

Design of the building

In 1606 the church was mentioned in the Inquisition of James 1 which noted that it had expanded to contain three chanceries – The Holy Trinity, St Mary's and St Katherine.

Thomas Drew R.H.A. writing in 1878 conjectured that the Protestant settlers established in Naas by the Duke of Ormond in 1648 probably altered the church in many respects according to the Jacobean style. In 1789 the sum of £118.11s3d was expended on the roof. In 1830 major work was carried out, including the addition of the wooden ceiling.

The building was completely renovated in 1989-1993 and subsequently there has been a constant effort of conservation and improvement, such as the renovation of the sanctuary in 2009, the tower in 2015 and ongoing work in the churchyard.

The church is one foot wider at the east end, than at the west end, and the east wall is remarkably out of square, the south wall being about two feet longer than the north wall. The chancel has the appearance of inclining to the north side. This is common to many medieval buildings.  One theory is that it mimics the head of Christ tilted on the cross.  Another theory is that medieval builders deliberately left some form of imperfection in the building as no one is perfect but God alone. There may have been a building or wall from an earlier church whose orientation did not happen to suit the ideas of the Welshmen, or they may have built the church close to an existing wall without regard to it being square.

Unfortunately, there is a lack of significant architectural evidence due to the centuries of plundering inflicted upon this historic building. From Edward Bruce in 1316 to Rory Og O'Moore in 1577, and throughout the seventeenth and eighteenth centuries, this building was ransacked, burned and despoiled, but thankfully survived it all.

1.        The Baptismal Font

The Baptismal font dates to the 11th Century and is a fine example of its period, predating the present church. Its black marble is decorated with leaf shaped ornaments representing God's creative power and Christ's in-dwelling in our lives through baptism. This font may be regarded as an important relic of the Celtic Christian Church. It was found abandoned in the church grounds around 1860 by Archdeacon De Burgh, who brought it into the church, where it rested on props of turned wood for many years before restoration by Thomas Drew in 1878.  This font is still used regularly today for baptisms and is a visual reminder of our Celtic heritage and history.

2.        The Memorials

The memorial on the south wall is dedicated to the Earl of Mayo, stipulating a bequest of £20 per annum forever to the trustees of the Church.

On the north side there are two plaques dedicated to the Eustace Family of Robertstown.

Also on the north side are memorials dedicated to The De Burgh Family. The De Burgh's came to Naas in 1700.

On the Chancel Wall the Wolfe Family of Forenaughts are remembered.

The Brass Eagle was presented by the De Robeck family who dedicated it to the memory of Coralie.

Many of the dedicated plaques that hang on the back gallery wall came from Killashee Church which was closed in the 1950s.

3.        Stained Glass Windows

The three light window in the Sanctuary of the Church is of French origin and dates to the 19th century.

There are two, two light windows in the Nave depicting Christ the light of the world, Christ as the Good Shepherd, King David and King Solomon. These windows are from Heaton, Butler and Bayne, and are dated 1882 and 1894.

4.        The Gallery

To mark the end of the 1989/1993 restoration, the Naas Quilters made and gifted a beautiful silk quilted cross to the church. They were inspired by the tiles on the floor dating from the 1830 restoration. These tiles are now covered with carpet to protect them.

The Gallery was restored in 1997 in memory of Martin De Robeck.

The organ pipes are a remnant of the Conacher organ that once stood in the present day side chapel. The organ was dated 1901 but was unfortunately beyond repair. Where this old organ stood we now have a beautiful space in which many intimate prayer services are held.

5.        The Crypt

The crypt is a honeycombed foundation structure under the church. In the 1980's, workers were digging outside on the south side of the church and came upon a wall of old brick some feet below the surface   An opening was made where once an archway had given  access to a sizeable

L-shaped room.

The crypt was the resting place of five coffins:  three male, one female and one child. The remains were those of the Mansfield family from Morristown Lattin and had lain undisturbed for over 300 years. They have since been buried in St Maudlin's Cemetery. Also half way down the church on the south side another tiny crypt area was discovered with a number of skeletal remains. The remaining crypt had been filled with rubble prior to this restoration.  There may well be more such crypts under the church and in the graveyard.  One fascinating theory is that there was a tunnel running from the church to the Moate in Naas and that the church may at one stage have had a series of vaults running underneath it.

Ancient Baptismal Font

The granite Baptismal Font preserved in the crypt is from early Christian times and would have been in use until the 11th Century.

The Sandstone Slab

The Carpenter Tomb slab in red sandstone was removed from the sanctuary to be preserved in the crypt. The wording is: 1655 Joshua Carpenter born at Lyme Devonshire in 1585 died in Denmark 1655 and was brought back here to be buried. Joshua Carpenter was involved as a stewart with Wentworth in the building of Jigginstown Castle on the Newbridge Road.

6.        The Sanctuary and Side Chapel

In 2009, work was undertaken to conserve and enhance the sanctuary.  The remnants of the non-functional organ were relocated to the West Wall above the gallery.  The organ room had to be completely renovated with new plastering, flooring and the excavation of a further underground area that housed the bellows of the organ. This created an intimate space which is used for midweek services and private prayer.  The Victorian tiles, were covered with carpet to protect them and removable staging was constructed to enable the church to adapt to 21st century worship.  The Pew runners were replaced and sanctuary chairs purchased in memory of loved ones. New lights and electrical sockets were installed along with a new sound system and associated wiring.  The electronic organ was moved to the back of the church and the interior of the building was completely re-painted. The Multimedia projector was installed in 2007.

The pulpit dates from the 19th century and in 2011 was given a facelift by the addition of wooden facing and lectern in memory of Jim Keyes.

The 19th century communion table, which had previously been concealed by an ancient fabric covering, was stripped back to its wood.  Please note how the table imitates the delicate stone carvings and symbols of the West Windows.  These quatrefoil motifs are echoed on the sanctuary carpet and chairs.

Churchyard

In 1672 the churchyard was railed in for the first time, but it remained a sort of thoroughfare until 1679.  There are a number of notable burials in the churchyard such as a stone dedicated to the Brophy brothers, who were killed in the ill fated Emmet Rebellion 1803.

Stand and look at the Church (southside) and notice the architectural Norman design of the church omitting the tower.

The outline of the crypt is still visible outside at the south side of the church. Above this there is a memorial plaque and in its dedication are a number of spelling mistakes.  If you look closely you will see where the spellings were corrected.

References

External links
Website

Churches in County Kildare
1620 establishments in Ireland
Naas
Church of Ireland church buildings in the Republic of Ireland

redpajama_set_name: RedPajamaWikipedia


Creative Why is a digital advertising and marketing agency in Orlando, FL. read more … 111 East Fairbanks Avenue, Winter Park, FL … Orlando Outdoor.
B est Farmers Market in Winter Garden, FL – Winter Garden Farmer"s Market, The … new Whole Foods in Dr. Phillips was going to feature a Farmer"s Market in…. Meet all your copying, printing and marketing needs at Staples Copy & Print at 3065 Daniels Road in Winter Garden, FL. We Offer PPC, Google Ads, Social Media Marketing, SEO & SEM.
We are a close-knit design and marketing agency located in the heart of Winter Garden, FL. We specialize in identities, ads, print, websites, video and … 321 is a full service digital marketing and digital creative agency located in Orlando, Fl.


text:
Warning: count(): Parameter must be an array or an object that implements Countable in /homepages/7/d309872558/htdocs/wp-content/plugins/meta-ographr/index.php on line 572
Added on September 21, 2011 Everett True Australian street press , Chad Parkhill , Everett True , Gotye , Lucy Cage , Mess And Noise , Music criticism , Rave Magazine , The Vine
These people are the enemy
I couldn't let the following exchange of views pass without comment.
There seems to be a certain type of person who hates anything that doesn't support their worldview … I have no idea why, maybe they feel threatened or something. The sort of sweeping, patronising, arrogant statements and gratuitous insults made by Chad Parkhill below are indicative of a certain attitude that is prevalent everywhere, especially on the Internet, not just among people who write about music for money, and certainly not just in Australia. It's just that I happen to live in Australia, and these were made by a fellow who writes for the street (music) press in my hometown.
(These blank ciphers, these willing sheep whose idea of a great review is one where they got free entry AND free drinks, they're the ones that hold the balance of power through sheer weight of numbers, not us. That's why we get shit like Gotye passing through mostly unchallenged in Australia AND people up in arms when we state we're not sure that's a good thing. "You're just hacking down the tall poppies," they bleat to overseas critics who have no idea what the fuck they're going on about. How is such myopic parochialism going to help anything? "If you can't say something nice, don't say anything at all," they cry. And, for fuck's sake, do NOT think about, or question, what you're doing. What's the point in that?)*
Doubtless, Chad thought he was offering Collapse Board and all who sail in her some sage, worldly advice. Sigh. Weird how he got so offended after I mildly disagreed with his reductionist theory of pop music: this, after an uncalled-for deluge of personal insults.
We can't let people like this get away with it. These people are the enemy. Make no mistake.
Taken from the comments section to Response To A Disgruntled Goyte Fan
Chad Parkhill says: Much like the question of whether or not Gotye's music is enjoyable, the question of whether this is a dialogue about or an in-house circlejerk is in the eye of the beholder. Surely we've all had enough of this?
Everett True says: Surely we've all had enough of this?
If you've had enough of this, why are you here?
Chad Parkhill says: Everett: I come here to read the vanishingly-small number of pieces that actually engage in writing about music (some of it decent!), as opposed to the increasingly-large number of pieces about Collapse Board itself, or how much Pitchfork sucks, or about how everyone other music critic in the world is crap, or about how Everett True is such a legend, mad contradictory bastard that he is, etc.
I know that your response to that will be "If you don't like it, don't read it," and you have every right to continue on with the project of installing new chips on your shoulder and building up CB's insular little mythos. I'll simply observe that every truly wonderful and successful cultural product (book, album, website—whatever) I've ever encountered has succeeded because it has its eye on the task ahead of it, not on its posterity and self-mythologising. Something to consider amongst the flood of manifestoes, meta-whinges, and complaints about how others suck at music criticism.
Everett True says:
I'll simply observe that every truly wonderful and successful cultural product (book, album, website—whatever) I've ever encountered has succeeded because it has its eye on the task ahead of it, not on its posterity and self-mythologising.
You're obviously not a fan of the following then:
(I could go on and list another few hundred thousand, but I've got to put the pizzas on the barbie)
Good on ya, mate. Clear head, and all that. Stick to the straight and narrow, that's best.
Chad Parkhill says: I can take some of that list and leave some of it, too. They're all very talented artists, though, and I can guarantee that any self-mythologising in their work is subservient to the focus of the work itself, *or* represents their artistic nadir. (Yes, some of that list have put out crap albums. Happens to everyone, often when they've stopped focusing on the work and started focusing on themselves.)
But, y'know, keep doing what you're doing, man. Keep working on the myth of Everett True and his merry band of fellow critics who stood up to Pitchfork and the general crapulence of modern music criticism and won. Maybe if you repeat it enough times it will magically come true.
I can guarantee that any self-mythologising in their work is subservient to the focus of the work itself, *or* represents their artistic nadir.
You really don't understand the first thing about popular music, do you?
Chad Parkhill says: See ya, Jerry. Good luck with your site.
matt says: I'm with Chad. I've had enough. You guys are just mean.
Lucy Cage says: "Mean"? Seriously? If you respond to criticism from readers, you're mean?! Even if the criticism is in the form of a personal attack?
I responded to Adrian's critique of Scott not because I thought Scott was offended (he wasn't and nor would I be) but because I thought Adrian had misunderstood what music criticism is for. There were fundamental differences between the way he thought a review should work and how Collapse Board approaches writing about music: the reply was for the sake of clarity. It's not a question of being surprised about the level of disagreement and certainly not one of not taking what you dish out: this is a dialogue, it aims to boost critical thinking about music and about writing. If anyone wants tick boxes and points, go elsewhere. If you're fascinated by the process, stick around and argue, because a critical, self-conscious approach to the way that one's adoration or loathing of music is articulated is part and parcel of anyone's (not just a writer's) relationship to music.
What I love about Collapse Board is that it sets the bar high: for music, for writing, for critical thought: that goes for its readers too! Better music, better writing, better listening. Passion in all things. That's a good thing.
Someone needs to tell Daniel Johnston – and quick!
P.S. Two good Australian music magazines. The Vine. Mess+Noise.
* This paragraph isn't aimed at Chad particularly. He has at least identified himself.
by Everett True
My name is Everett True. I am a music critic. This is what I do. I criticise music. The clue is in my job description – music critic. I do not consider myself a journalist, as I do not research or report hard news. I do not consider myself a commentator as I believe that everyone should be a participant. I criticise people and in return I am not surprised if other people criticise me. It is part of the whole deal of being in the public arena. I am Everett True. Believe in me and I have power like a God. Quit believing in me and I no longer exist.
16 Responses to These people are the enemy
How is this necessary? I'll admit, the "Gotye debate" has inspired an interesting back-and-forth about the nature of music writing, in addition to a thoughtful piece about responding to negative criticism (at least I'm assuming that Wallace Wylie's "8 Things You Should Avoid…" was a response to the Gotye backlash). More than an album comprised of background music for Australian coffeehouses has any right to inspire. Yet singling out a commenter and labeling them as the "enemy" of righteous music criticism just seems excessive. And yes, mean-spirited. I've only been a CB reader for a few days now, but you've obviously got a talented stable of writers, who are capable of covering a wide berth of artists, genres and topics. Let this fucking go.
Or at least focus your ire on a more interesting target.
Everett True September 21, 2011 at 7:08 pm
Greg, this is writing. It's not like being stuck in the toilets at the Powerhouse with terrible stomach cramps while they pump Phil Collins through the speakers. If you don't like the way that the Internet is changing music criticism from a one-sided conversation into a multi-sided dialogue, you can always turn the page.
There's plenty – plenty – to divert your attention elsewhere. Welcome on board.
Joseph Kyle September 21, 2011 at 10:14 pm
Greg–I don't see how it would be any different, were ET just to comment beneath it. He's merely highlighting a conversation, and weighing in…
Johnny Danger September 21, 2011 at 10:15 pm
Greg says: How is this necessary?
Entirely necessary. It is this collective uncriticalness of aus. music Industry that creates the stacks-on-lets-get-behind-this-so-we-can-get-our-paycheck. Because middle of the road adult contemporary shite sells to the desperately trying to hang onto cred gen xers because they are the only ones who spend a cent on the Industry.
For some bizarre reason young people are believing the hype (I guess they always have – Phil Collins and Sting did sell back in the day).
(see I don't have a hat the ring due to being semi literate but DO have a hat in the ring 'cause I have ears and they hurt whenever Gotye, Seeker, Lover, Keeper or any of middle and upper tier of touring oz acts of the beige brigade)
There is waaaaay more interesting music being made in this country right now – music that is exciting, festive, fun, thrilling, makes you want to get up and dance and scream and buy booze and cd's and listen to the radio. NONE of it is in the Industry, what we get is so stupidly safe that Gotye is seen as edgy. As the Industry gets less bums on seats the safer the music is getting – which I think is a stupid, patronising and offensive response.
The last few years I have seen quite a few great acts play to twenty people – and the next week see 300+ in the same venue packed for a dull as dishwater 'name' that the Industry is behind. The public – and that means in my town the 'no I'm not really square' gen X brigade with $ – only goes to things and buys the music that the Industry tells them to — because they do not want to not like what their peers (colour supplement alert!) like.
The Industry does not depend on music – it depends on the human need to maintain status within the group.
We can do better than this, and it starts here with us music listeners and lovers championing the brilliant and bollocking the bullshit. THAT is why it is necessary, otherwise the music dies, the Industry dies and my ears will wither off.
Everett True September 21, 2011 at 10:37 pm
There is waaaaay more interesting music being made in this country right now – music that is exciting, festive, fun, thrilling, makes you want to get up and dance and scream and buy booze and cd's and listen to the radio. NONE of it is in the Industry, what we get is so stupidly safe that Gotye is seen as edgy.
Dude, quick! Link us to five! Or 10. Or whatever.
Greg September 22, 2011 at 5:24 am
Maybe I should clarify my post slightly. I'm okay with music criticism initiating a "multi-sided dialogue." Hell, I'd like to see it more often. There's a lot of complacency and slack in the global music press, and most "professional" reviews are too placid and boring to generate any kind of a discourse. And yes, a lot of great alternative music is unfairly brushed aside for not conforming to record industry or Pitchfork standards. No argument there. That said, this particular debate has run its course. Everyone has more or less said their piece, and by this point, it's starting to sound like internet drama played for insightful meta-commentary. This post especially adds nothing to the debate (the reason I asked "How is this necessary?"). You've singled out one of your dissenters and called him the scourge of music criticism for disagreeing with you. It's gone from a thoughtful discussion about the critic's role to – well, Beavis and Butt-head punching each other in the face. Again, I respect what you guys are doing on this site, but I see no point in dragging this out. Not only have you beaten it to death, the bones are starting to disintegrate.
Everett True September 22, 2011 at 7:03 am
It's gone from a thoughtful discussion about the critic's role to – well, Beavis and Butt-head punching each other in the face.
I think there's an element of that, yes. Which is why I ran with that visual. But only an element, mark you.
Darragh September 22, 2011 at 7:09 am
Hi ET. I've regularly read and occasionally contributed here to Collapse Board and enjoy most of its content but this post bothers me. It says that there "certain type of person who hates anything that doesn't support their worldview " in a post labelling these people as 'enemies'. It doesn't strike me at constructive dialogue at all but rather a conversation that's got heated, got out of hand etc. I think Greg here has hit the nail on the head when he says that it's moved on from a thoughtful discussion.
Furthermore, I disagree with the portrayal of street press as one that's intimately hand-in-hand with industry. From my time contributing to the local rag, I've never got free drinks or anything of the sort. I know from other people there that this rarely would be the case. I think you have to accept that in Australia there are limited opportunities for people to write about music without working for street press. (In the interest of disclosing my comment, I should point out that I happen to write for the same street press publication as Chad though I would hold this reviewer regardless).
Also, I'm pretty sure Mess+Noise and The Vine reviewed Gotye favourably, so I'm not sure they're the best examples to use for talking about quality Australian music publications assuming that the underlying argument is to state that street press review stuff like Gotye positively and other more 'high-brow' publications don't.
Darragh, you know I love ya. And I was quite at pains to stress within this post that I don't think all the Australian street press behaves this way, just certain elements. Of course I think that most people writing for the street press are doing it for the love of music. (Doesn't make them good writers of course, but that's more a failing with their editors than with the writers themselves.) If I really felt otherwise I sure as shit wouldn't be publishing your work now, would I? But you also have to appreciate that when someone layers personal insult after personal insult at me – uncalled-for, as well – then I will react. It would be fucking weird if I didn't, don't you agree? I listed M+N and The Vine because I think they step outside the (self-imposed) boundaries of the street press every now and then. I'm sure that if I look hard enough I 'd find some decent articles within the main print street press as well.
It's absurd to think I despise the street press unreservedly. I would imagine that pretty much every Australian writer who contributes here to Collapse Board also contributes to the street press, and I sure don't hate them. What I do not like, however, is the prevalent belief – as exemplified by Chad's comments – that there is only one way to write about music, and if you disagree with that you must be an idiot. Or self-serving. Or something.
His comments were particularly pompous, asinine and gratuitously insulting. That's why I picked up on them.
P.S. Good on ya for having enough pride in what you do to be moved to defend it, though. That pride in your own work is one of the reasons I use you, for sure.
ET, have you, in your time of being a music critic, been offered free entry and free drinks to write a review for an artist?
Everett True September 22, 2011 at 11:47 am
Plenty of times. Free drugs, sex, plane tickets, hotel rooms, hard cash … Of course I did. In my time, I have been an incredibly influential, well-known music critic. Still am, depending on where you look.
And did I accept these offers? Of course I did … depending on the situation, and what was on offer, and how it was offered, and what sort of strings came attached, etc. Mostly it came down to one simple question: Would I have liked the music under offer without any of these inducements? Yes? Then fucking induce away. No? Then be prepared for me to bite yr hand and bite it fierce. I might give you fair warning, I might not. (I have never been a *tame* music critic, as many PRs and record companies and band members can attest.)
This is all a matter of (considerable) record.
I've never been anything less than upfront about what I do, and how I do it.
But I'm guessing you already knew that. Correct?
This question appears to be referring to, but missing the delicate nuances of, the phrase:
…these willing sheep whose idea of a great review is one where they got free entry AND free drinks…
Communicating my love for music through my writing has always been way more important to me than the inducements on offer. Just a free CD or guest-list place alone seems to be motivation enough for the majority of folk who write about music. "Who gives a crap what the quality of writing is like? It's only music criticism. I got a free CD."
No. It is NEVER *only* music criticism.
HowlingEverett September 22, 2011 at 8:05 pm
Wait, what, Mr. True?
You're the kind of journalist who takes kickbacks "depending on what's on offer and what strings are attached" and you're making the cardinal sin of assuming that your experience is the same as everyone else's in the music industry?
The 'kickbacks' journalists from Rave such as Chad Parkhill (full disclosure, I'm a personal friend of his) get are tickets to the show they're attending (without which, many of them wouldn't be able afford the quantities of shows they review). Period. Aside from that, the per article wage a Rave journalist receives is so laughably small (as in, less than $50) as to be negligible. The only reason to get a job for Rave is because you're trying to step up the ladder into serious journalism or, and lets just pause on this one: because you really, actually love music.
What you seem to be saying in your post, Mr. True, is that you think the people who continue to critique music in the face of the fact that they can't even make a living from it are the enemy. It's dishonest to review music because you love music. Unless you're making a living and taking 'Free drugs, sex, plane tickets, hotel rooms, hard cash' then you have no right to have an educated opinion on the quality of music.
Funny old world you live in. Sure isn't any one I've ever seen.
As an amusing postfix, all of the bands (and one visual artist) you mentioned are as amazing as they are strictly because of the way, in their time, they redefined (or in some cases defined) the genres in which they worked. Each new Beatles album was exciting because it was different from the last, and because the songs were fucking amazing, not because of the mythology that grew up around them. The mythology comes afterwards, so that the old fans who have stopped listening to anything new can get themselves a warm fuzzy with people of like mind.
Someone else unable to read what's on the screen in front of him/her. Sigh.
I'm not quite sure why I have to repeat the same answer twice, but here goes.
The question above appears to be referring to, but missing the delicate nuances of, the phrase:
Next time you leave gratuitous insults anonymously, you're barred.
@HowlingEverett says: What you seem to be saying in your post, Mr. True, is that you think the people who continue to critique music in the face of the fact that they can't even make a living from it are the enemy. It's dishonest to review music because you love music.
Yeah, that could have possibly – possibly – been what I was saying if I hadn't already taken the trouble to further clarify my post in this reply to Darragh. Here's the first paragraph of it again. And I really, REALLY am not sure why I have to repeat the same answer twice.
Darragh, you know I love ya. And I was quite at pains to stress within this post that I don't think all the Australian street press behaves this way, just certain elements. Of course I think that most people writing for the street press are doing it for the love of music. (Doesn't make them good writers of course, but that's more a failing with their editors than with the writers themselves.)
Please learn to read what's on the screen in front of you before commenting next time. It will save an awful lot of time and effort.
Wallace Wylie September 23, 2011 at 12:58 am
Just for the sake of it I'm going to throw in my tuppence worth about the mythology surrounding bands. In regards to The Beatles, while in hindsight it's easy to create some narrative about The Beatles changing the world with each new release the truth is actually very different. When The Beatles became huge, their created mythology helped enormously. They played up to the idea of 'four lads from Liverpool' and, even if Lennon grumbled, they all willingly made "A Hard Days Night" and "Help", which were huge, expensive exercises in mythology building. People often forget that they made these movies in conjunction with the albums, with one promoting the other. The thing that nobody mentions is, by '65 The Beatles sales were dipping. No, not in some huge noticeable way (the albums and singles were still going to number on), but behind the scenes there was talk that the new direction they were taking would ultimately lose them their fanbase. When "Revolver" came out it was the lowest selling Beatles album up to that point. The music press was very different in those days, so it's not like it was greeted with the overwhelming praise that something like "Kid A" was greeted with (and which everybody now pretends it wasn't greeted with). Then, when the band released "Penny Lane/Strawberry Fields Forever", it didn't go to number one. Many people were writing articles asking if The Beatles were done. What saved them? The unbelievable act of self-mythologising that was "Sgt. Peppers Lonely Hearts Club Band". Everything about it was designed to create a new myth for The Beatles. The songs, the packaging, the front cover (very expensive, the likes of which had never been seen before). It worked, and "Sgt. Pepper…" put The Beatles back on top and cemented their reputation as the biggest band in the world. Yet it was a triumph of image over substance as "Sgt. Pepper.." is their weakest album, by a country mile. I'm not saying it's a disaster but it struggles to exist outside of the context of 1967, and is the only Beatles album that seems trapped in a time-warp. The much superior "Revolver" did not have the same self-mythologising pizzazz and as such sold much less in comparison. Hindsight often allows people to create false narratives about important events, but instead of parroting accepted truths it sometimes helps to dig a little deeper.
Bob Dylan self-mythologised from day one. He changed his name, made up stories about his past, got involved in a folk-music scene that he contributed some era-defining songs to but which he ultimately didn't care about that much. In private, and since, Dylan admitted that he really didn't give a shit about many of the social concerns of other Greenwich Village folkies but instead he saw a way of making a name for himself. He had the talent and the chutzpah to pull it off, so that's exactly what he did, but once he had made a big enough name for himself he abandoned it and recast himself as a hyper-literate, jive-talking James Dean. Right now Dylan seems to have convinced the entire world that he is some kind of national monument that guards and protects American folk music. This development in self-mythologising actually fueled some of his best work in years. "Modern Times", however, was almost all self-mythologising and, outside of three songs, had nothing of substance. Nobody noticed and it was praised to the heavens as another late-period Dylan classic.
The White Stripes got all that press not only for the music but their excellent image building. Red and white, brother and sister, faux-naivety and the simplicity of the blues…these were all masterstrokes in self-mythologising and it happened straight out of the traps. In fact it fueled their best work. The more the mythology faded the less interesting The White Stripes became.
I could go on, and I think this is exactly the kind of stuff Everett was referring to when he made that list. I'm also sure he thought it didn't need explaining. That surely everybody knew more often than not self-mythologising and great works of art go hand-in-hand. In fact they need one another.

redpajama_set_name: RedPajamaCommonCrawl


text:
Australia. Aboriginal and Torres Strait Islander Commission
Addressing priorities in indigenous affairs : statement by Senator the Honourable John Herron, Minister for Aboriginal and Torres Strait Islander Affairs, 12 May 1998
Canberra : Australian Govt. Publishing Service, 1998
ADDRESSING PRIORITIES IN INDIGENOUS AFFAIRS 1
1. Accountability 11
2. Improving Outcomes in Key Areas 12
3. Promoting Economic Independence 18
4. Support for Women and Families 19
5. The Importance of Land 21
6. Recognising and Protecting Culture and Heritage 23
7. Law and Justice 25
8. Torres Strait Islands 26
9. Reconciliation 27
10. The Future 28
Appendix 1 Commonwealth Funded Programmes for Indigenous People 1995-96 to 1998-99 29
Appendix 2 Commonwealth Programmes for Indigenous People by Portfolio 36
Appendix 3 List of Acronyms 140
Australia. Aboriginal and Torres Strait Islander Commission & Herron, John. (1998). Addressing priorities in indigenous affairs : statement by Senator the Honourable John Herron, Minister for Aboriginal and Torres Strait Islander Affairs, 12 May 1998 Retrieved January 18, 2021, from http://nla.gov.au/nla.obj-1665643718
Australia. Aboriginal and Torres Strait Islander Commission and Herron, John. Addressing priorities in indigenous affairs : statement by Senator the Honourable John Herron, Minister for Aboriginal and Torres Strait Islander Affairs, 12 May 1998 Canberra: Australian Govt. Publishing Service, 1998. Web. 18 January 2021 <http://nla.gov.au/nla.obj-1665643718>
Australia. Aboriginal and Torres Strait Islander Commission & Herron, John. 1998, Addressing priorities in indigenous affairs : statement by Senator the Honourable John Herron, Minister for Aboriginal and Torres Strait Islander Affairs, 12 May 1998 Australian Govt. Publishing Service, Canberra viewed 18 January 2021 http://nla.gov.au/nla.obj-1665643718
| author1=Australia. Aboriginal and Torres Strait Islander Commission.
| author2=Herron, John.
| title=Addressing priorities in indigenous affairs : statement by Senator the Honourable John Herron, Minister for Aboriginal and Torres Strait Islander Affairs, 12 May 1998
| section=i, 135 pages ; 25 cm.
| isbn=064452488X
| issue=PP no. 78 of 1998
| publisher=Australian Govt. Publishing Service
Until 2048 [Created/Published Date + 50 Years]
Australian Capital Territory - Federal/national


text:
SM Supermalls
SM Foundation
Marikina's PWDs and elderly receive disaster resiliency training through SM Cares' Emergency Preparedness Forum
Hundreds of Marikeneños, many of them PWDs and senior citizens, actively participated in SM Cares' Emergency Preparedness Forum 2019, held recently at SM City Marikina, one of the most disaster prone areas in the country as it lies on the dreaded Valley Fault Line and the Marikina river cuts across the midwest portion of the city.
Facilitating the forum were Department of Science and Technology (DOST) undersecretary and Philippine Institute of Volcanology and Seismology (PHIVOLCS) director Dr. Renato Solidum Jr., a leading expert in geology and seismology, along with Dr. Ted Esguerra, who is a very active member of numerous emergency preparedness and disaster response units around the globe. Both highly-regarded experts imparted knowledge about natural disasters and how to properly respond to them.
"We believe that it is very important for everyone to become more prepared. It is our mission to support communities in becoming more disaster-resilient through learning, so that we can properly respond to these kinds of situations wherever you are, whoever you may be," said Engr. Bien Mateo, SM Cares Program Director for Persons with Disabilities. SM Cares is the corporate social responsibility arm of SM Prime Holdings.
Esperanza Cruz, office of the senior citizens affairs' head, said the information she has gathered from the forum will allow her to teach her family basic and proper techniques for survival. "Napakalaking bagay na magkaroon kami ng kaalaman tungkol sa preparedness, at maibahagi namin sa aming pamilya."
During heavy rains, the city's main tributary and several other creeks running through residential areas swell, with the overflows affecting more than 2,000 households. Gil Flores, Marikina PWD affairs officer shared that this initiative of SM Cares has given PWDs an advantage. "Malaking tulong ito para sa mga taong tulad namin na may kapansanan. Dahil may ganito tayong forum, aware na kami na mapaghandaan kung ano man mangyayaring disaster."
SM Marikina was able to withstand the super typhoon "Ondoy" as it was built on the foundation of resilience. By design, SM City Marikina is an elevated mall resting on stilts on a six-hectare property within the Marikina River Watershed. As part of its disaster resilience design, SM Prime built SM City Marikina 20 meters farther than the standard regulation of buildings – 90 meters away from the Marikina River centerline. The stilts are also cylindrical in shape, a science-based solution that allows water to flow through the mall structure. This distance helped reduce the risks of damaging the mall during floods.
These features allowed water to flow freely through the parking structure while the mall stands on the third floor lifted by supportive stilts during extreme floods. With these attributes, the mall is also able to open immediately for business while offering a safe haven and free parking to residents of the city during severe typhoons.
SM's Emergency Preparedness Forum is in line with the United Nations Sustainable Development Goal No. 11: To make cities inclusive, safe, resilient and sustainable. It is projected that by 2050, 70% of the world's population will be living in cities, making sustainability a critical priority. SM steps forward with the best efforts to work together with government agencies and community members, are collectively engaged in pursuing these objectives/
The forum supports initiatives of ARISE Philippines of the United Nations Office for Disaster Risk Reduction (UNDRR). It aims to create risk-resilient societies by working with the private sector to incorporate DRR in the core of their business and stakeholder engagement. Hans Sy, SM Prime Holdings executive committee chairman, is the only Filipino Global Board Member of the UNDRR ARISE Private Sector Alliance for Resilient Societies.
As a responsible member of the community, SM Supermalls, through the CSR Programs of SM Cares, aims to serves as a catalyst for positive change in society. To know more about SM Cares, you may visit https://www.facebook.com/OfficialSMCares/, or email smcares@smsupermalls.com.
Copyright © 2022 SM Cares - All Rights Reserved


text:
<?php

namespace PHPExiftool\Driver\Tag\OpenEXR;

use JMS\Serializer\Annotation\ExclusionPolicy;
use PHPExiftool\Driver\AbstractTag;

/**
 * @ExclusionPolicy("all")
 */
class GPSLatitude extends AbstractTag
{

    protected $Id = 'latitude';

    protected $Name = 'GPSLatitude';

    protected $FullName = 'OpenEXR::Main';

    protected $GroupName = 'OpenEXR';

    protected $g0 = 'OpenEXR';

    protected $g1 = 'OpenEXR';

    protected $g2 = 'Image';

    protected $Type = '?';

    protected $Writable = false;

    protected $Description = 'GPS Latitude';

    protected $local_g2 = 'Location';

}

redpajama_set_name: RedPajamaGithub